

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Crear una capa personalizada de servidor Tomcat
<a name="create-custom"></a>

**importante**  
El AWS OpsWorks Stacks servicio llegó al final de su vida útil el 26 de mayo de 2024 y se ha desactivado tanto para los clientes nuevos como para los existentes. Recomendamos encarecidamente a los clientes que migren sus cargas de trabajo a otras soluciones lo antes posible. Si tienes preguntas sobre la migración, ponte en contacto con el AWS Support equipo en [AWS Re:post](https://repost.aws/) o a través de Premium [AWS Support](https://aws.amazon.com/support).

**nota**  
En este tema se describe cómo implementar una capa personalizada en una pila de Linux. No obstante, los principios básicos y parte del código también se pueden adaptar para implementar capas personalizadas en pilas de Windows, en particular los de la sección sobre implementación de aplicaciones.

La forma más sencilla de usar paquetes no estándar en las instancias de OpsWorks Stacks es [extender](workingcookbook-extend-package.md) una capa existente. No obstante, este método instala y ejecuta en las instancias de la capa tanto los paquetes estándar como los que no los son, algo que no siempre es deseable. Un método más exigente pero también de mayor alcance consiste en implementar una capa personalizada, lo cual ofrece un control casi total de las instancias de la capa, incluido lo siguiente: 
+ Qué paquetes se instalan.
+ Cómo se configura cada paquete.
+ Cómo se implementan aplicaciones de un repositorio en la instancia.

Ya sea a través de la consola o la API, puede crear y administrar una capa personalizada como cualquier otra, tal y como se describe en [Capas personalizadas](workinglayers-custom.md). No obstante, las recetas integradas de una capa personalizada solo llevan a cabo algunas tareas básicas, como instalar un cliente de Ganglia que registre las métricas en un nodo maestro de Ganglia. Para que las instancias de una capa personalizada tengan algo más que una funcionalidad mínima, debe implementar uno o varios libros de recetas personalizados con recetas de Chef y sus archivos relacionados, para administrar las tareas de instalación y configuración de paquetes, implementación de aplicaciones, etcétera. Ahora bien, no tiene que implementar todo desde cero. Por ejemplo, si almacena las aplicaciones en uno de los repositorios estándar, puede utilizar las recetas de implementación integradas para administrar gran parte del trabajo de instalar las aplicaciones en las instancias de la capa.

**nota**  
Si no conoce Chef, es conveniente que lea primero [Cookbooks 101](cookbooks-101.md), un tutorial en el que se introducen los conceptos básicos de la implementación de libros de recetas para realizar varias tareas habituales. 

En el tutorial siguiente se describe cómo implementar una capa personalizada compatible con un servidor de aplicaciones Tomcat. La capa se basa en un libro de recetas personalizado denominado Tomcat, que incluye recetas para administrar la instalación e implementación de paquetes, etcétera. En el tutorial se presentan extractos del libro de recetas de Tomcat. [Puedes descargar el libro de cocina completo desde su repositorio. GitHub ](https://github.com/amazonwebservices/opsworks-example-cookbooks/tree/master/tomcat) Si no está familiarizado con [Opscode Chef](http://www.opscode.com/chef/), conviene que lea primero [Cookbooks and Recipes](workingcookbook.md).

**nota**  
OpsWorks Stacks incluye una [capa Java App Server](layers-java.md) con todas las funciones para uso en producción. El objetivo del libro de recetas de Tomcat es mostrar cómo se implementan las capas personalizadas, por lo que solo admite una versión limitada de Tomcat que no incluye características como SSL. Para obtener un ejemplo de implementación con total funcionalidad, consulte el libro de recetas [opsworks\$1java](https://github.com/aws/opsworks-cookbooks/tree/release-chef-11.10/opsworks_java) integrado.

El libro de recetas de Tomcat admite una capa personalizada cuyas instancias tienen las siguientes características:
+ Admiten un servidor de aplicaciones Tomcat Java con un front-end de Apache.
+ Tomcat se configura para permitir que las aplicaciones utilicen un objeto `DataSource` de JDBC para conectarse a una instancia de MySQL independiente que sirve como almacén de datos de back-end.

El libro de recetas de este proyecto incluye varios componentes clave:
+ Un [archivo de atributos](create-custom-attributes.md) que contiene los valores de configuración que utilizan las distintas recetas.
+ Las [recetas de instalación](create-custom-setup.md) que se asignan al [evento del ciclo de vida](workingcookbook-events.md) Setup de la capa. Se ejecutan después de que una instancia haya arrancado y efectuado tareas como, por ejemplo, instalar paquetes y crear los archivos de configuración.
+ Las [recetas de configuración](create-custom-configure.md) se asignan al evento Configure del ciclo de vida de la capa. Se ejecutan después de los cambios de configuración de la pila, principalmente cuando las instancias entran online o se quedan sin conexión, y controlan los cambios de configuración necesarios.
+ Las [recetas de implementación](create-custom-deploy.md) se asignan al evento Deploy del ciclo de vida de la capa. Se ejecutan después de las recetas de configuración y cuando implementa manualmente una aplicación para instalar el código y los archivos relacionados en las instancias de una capa y controlar tareas relacionadas, por ejemplo, reiniciar los servicios.

En la última sección, [Crear una pila y ejecutar una aplicación](create-custom-stack.md), se describe cómo crear una pila que incluye una capa personalizada basada en el libro de recetas de Tomcat, y cómo implementar y ejecutar una aplicación JSP sencilla que muestra datos de una base de datos MySQL que se ejecuta en una instancia que pertenece a otra capa MySQL.

**nota**  
Las recetas del libro de cocina de Tomcat dependen de algunas OpsWorks recetas integradas en Stack. Para dejar claro cuál es el origen de cada receta, en este tema se identifican las recetas utilizando la convención *cookbookname*::*recipename* de Chef.

**Topics**
+ [Archivo de atributos](create-custom-attributes.md)
+ [Recetas de instalación](create-custom-setup.md)
+ [Recetas de configuración](create-custom-configure.md)
+ [Recetas de implementación](create-custom-deploy.md)
+ [Crear una pila y ejecutar una aplicación](create-custom-stack.md)

# Archivo de atributos
<a name="create-custom-attributes"></a>

**importante**  
El AWS OpsWorks Stacks servicio llegó al final de su vida útil el 26 de mayo de 2024 y se ha desactivado tanto para los clientes nuevos como para los actuales. Recomendamos encarecidamente a los clientes que migren sus cargas de trabajo a otras soluciones lo antes posible. Si tienes preguntas sobre la migración, ponte en contacto con el AWS Support equipo en [AWS Re:post](https://repost.aws/) o a través de Premium [AWS Support](https://aws.amazon.com/support).

Antes de ver las recetas, es útil examinar primero el archivo de atributos del libro de recetas de Tomcat, que contiene diversas opciones de configuración que utilizan las recetas. Los atributos no son necesarios; puede simplemente codificar estos valores en las recetas o en las plantillas. Sin embargo, si defines los ajustes de configuración mediante atributos, puedes usar la consola o la API de OpsWorks Stacks para modificar los valores mediante la definición de atributos JSON personalizados, lo que resulta más sencillo y flexible que volver a escribir el código de la receta o de la plantilla cada vez que quieras cambiar un ajuste. Este método permite, por ejemplo, utilizar el mismo libro de recetas con varias pilas, pero configurar el servidor Tomcat de manera diferente para cada pila. Para obtener más información acerca de los atributos y el modo de anularlos, consulte [Anulación de atributos](workingcookbook-attributes.md).

En el siguiente ejemplo se muestra el archivo de atributos `default.rb` completo, que se encuentra en el directorio `attributes` del libro de recetas de Tomcat.

```
default['tomcat']['base_version'] = 6
default['tomcat']['port'] = 8080
default['tomcat']['secure_port'] = 8443
default['tomcat']['ajp_port'] = 8009
default['tomcat']['shutdown_port'] = 8005
default['tomcat']['uri_encoding'] = 'UTF-8'
default['tomcat']['unpack_wars'] = true
default['tomcat']['auto_deploy'] = true
case node[:platform]
when 'centos', 'redhat', 'fedora', 'amazon'
  default['tomcat']['java_opts'] = ''
when 'debian', 'ubuntu'
  default['tomcat']['java_opts'] = '-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC'
end
default['tomcat']['catalina_base_dir'] = "/etc/tomcat#{node['tomcat']['base_version']}"
default['tomcat']['webapps_base_dir'] = "/var/lib/tomcat#{node['tomcat']['base_version']}/webapps"
default['tomcat']['lib_dir'] = "/usr/share/tomcat#{node['tomcat']['base_version']}/lib"
default['tomcat']['java_dir'] = '/usr/share/java'
default['tomcat']['mysql_connector_jar'] = 'mysql-connector-java.jar'
default['tomcat']['apache_tomcat_bind_mod'] = 'proxy_http' # or: 'proxy_ajp'
default['tomcat']['apache_tomcat_bind_config'] = 'tomcat_bind.conf'
default['tomcat']['apache_tomcat_bind_path'] = '/tc/'
default['tomcat']['webapps_dir_entries_to_delete'] = %w(config log public tmp)
case node[:platform]
when 'centos', 'redhat', 'fedora', 'amazon'
  default['tomcat']['user'] = 'tomcat'
  default['tomcat']['group'] = 'tomcat'
  default['tomcat']['system_env_dir'] = '/etc/sysconfig'
when 'debian', 'ubuntu'
  default['tomcat']['user'] = "tomcat#{node['tomcat']['base_version']}"
  default['tomcat']['group'] = "tomcat#{node['tomcat']['base_version']}"
  default['tomcat']['system_env_dir'] = '/etc/default'
end
```

La configuración propiamente dicha se analiza más adelante en la sección relacionada. Las notas siguientes son de aplicación general:
+ Todas las definiciones de nodo son de tipo `default`, de forma que puede anularlas con [atributos de JSON personalizado](workingcookbook-json-override.md).
+ El archivo utiliza una declaración `case` para definir valores de atributo condicionalmente en función del sistema operativo de la instancia.

  El nodo `platform` lo genera la herramienta Ohai de Chef y representa el sistema operativo de la instancia. 

# Recetas de instalación
<a name="create-custom-setup"></a>

**importante**  
El AWS OpsWorks Stacks servicio finalizó su vida útil el 26 de mayo de 2024 y se ha desactivado tanto para los clientes nuevos como para los existentes. Recomendamos encarecidamente a los clientes que migren sus cargas de trabajo a otras soluciones lo antes posible. Si tienes preguntas sobre la migración, ponte en contacto con el AWS Support equipo en [AWS Re:post](https://repost.aws/) o a través de Premium [AWS Support](https://aws.amazon.com/support).

Las recetas de instalación se asignan al evento Setup del [ciclo de vida](workingcookbook-events.md) de la capa y se ejecutan después de que se arranca una instancia. Realizan tareas como instalar paquetes, crear los archivos de configuración e iniciar servicios. Cuando terminen de ejecutarse las recetas de configuración, OpsWorks Stacks ejecuta las [recetas de implementación](create-custom-deploy.md) para implementar cualquier aplicación en la nueva instancia.

**Topics**
+ [tomcat::setup](#create-custom-setup-setup)
+ [tomcat::install](#create-custom-setup-install)
+ [tomcat::service](#create-custom-setup-service)
+ [tomcat::container\$1config](#create-custom-setup-config)
+ [tomcat:: apache\$1tomcat\$1bind](#create-custom-setup-bind)

## tomcat::setup
<a name="create-custom-setup-setup"></a>

La receta `tomcat::setup` se asignará a un evento Setup del ciclo de vida de la capa.

```
include_recipe 'tomcat::install'
include_recipe 'tomcat::service'

service 'tomcat' do
  action :enable
end

# for EBS-backed instances we rely on autofs
bash '(re-)start autofs earlier' do
  user 'root'
  code <<-EOC
    service autofs restart
  EOC
  notifies :restart, resources(:service => 'tomcat')
end

include_recipe 'tomcat::container_config'
include_recipe 'apache2'
include_recipe 'tomcat::apache_tomcat_bind'
```

La receta `tomcat::setup` es, en gran medida, una metarreceta. Incluye un conjunto de recetas dependientes que controlan la mayoría de los detalles de instalación y configuración de Tomcat y los paquetes relacionados. La primera parte de `tomcat::setup` ejecuta las siguientes recetas, que se tratarán más adelante: 
+ La receta [tomcat::install](#create-custom-setup-install) instala el paquete del servidor Tomcat.
+ La receta [tomcat::service](#create-custom-setup-service) configura el servicio de Tomcat.

La parte central de `tomcat::setup` habilita e inicia el servicio de Tomcat:
+ El [recurso de servicio](https://docs.chef.io/chef/resources.html#service) de Chef habilita el servicio de Tomcat en el arranque.
+ El [recurso bash](https://docs.chef.io/chef/resources.html#bash) de Chef ejecuta un script de Bash para iniciar el daemon autofs, necesario para las instancias respaldadas por Amazon EBS. El recurso, a continuación, notifica al recurso `service` que reinicie el servicio de Tomcat.

  Para obtener más información, consulte: [autofs](https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Storage_Administration_Guide/s2-nfs-config-autofs.html) (para Amazon Linux) o [Autofs](https://help.ubuntu.com/community/Autofs) (para Ubuntu).

La última parte de `tomcat::setup` crea archivos de configuración, e instala y configura el servidor front-end de Apache:
+ La receta [tomcat::container\$1config](#create-custom-setup-config) crea los archivos de configuración.
+ La `apache2` receta (que es la abreviatura de`apache2::default`) es una receta integrada de OpsWorks Stacks que instala y configura un servidor Apache.
+ La receta [tomcat:: apache\$1tomcat\$1bind](#create-custom-setup-bind) configura el servidor Apache para que actúe como front-end para el servidor Tomcat.

**nota**  
A menudo ahorrará tiempo y esfuerzo si utiliza recetas integradas para realizar algunas de las tareas necesarias. Esta receta utiliza la receta `apache2::default` integrada para instalar Apache en lugar de implementarlo desde cero. Para ver otro ejemplo del uso de las recetas integradas, consulte [Recetas de implementación](create-custom-deploy.md).

En las siguientes secciones se describen más en detalle las recetas de configuración de los libros de recetas de Tomcat. Para obtener más información acerca de las recetas de `apache2`, consulte [opsworks-cookbooks/apache2](https://github.com/aws/opsworks-cookbooks/tree/release-chef-11.4/apache2).

## tomcat::install
<a name="create-custom-setup-install"></a>

La receta `tomcat::install `instala el servidor Tomcat, el OpenJDK y una biblioteca de conectores de Java que administra la conexión con el servidor MySQL.

```
tomcat_pkgs = value_for_platform(
  ['debian', 'ubuntu'] => {
    'default' => ["tomcat#{node['tomcat']['base_version']}", 'libtcnative-1', 'libmysql-java']
  },
  ['centos', 'redhat', 'fedora', 'amazon'] => {
    'default' => ["tomcat#{node['tomcat']['base_version']}", 'tomcat-native', 'mysql-connector-java']
  },
  'default' => ["tomcat#{node['tomcat']['base_version']}"]
)

tomcat_pkgs.each do |pkg|
  package pkg do
    action :install
  end
end

link ::File.join(node['tomcat']['lib_dir'], node['tomcat']['mysql_connector_jar']) do
  to ::File.join(node['tomcat']['java_dir'], node['tomcat']['mysql_connector_jar'])
  action :create
end

# remove the ROOT webapp, if it got installed by default
include_recipe 'tomcat::remove_root_webapp'
```

La receta lleva a cabo las siguientes tareas:

1. Crea una lista de paquetes que se van a instalar según el sistema operativo de la instancia.

1. Instala cada paquete de la lista.

   El [paquete de recursos](https://docs.chef.io/chef/resources.html#id146) de Chef utiliza el proveedor adecuado (`yum` para Amazon Linux y `apt-get` para Ubuntu) para controlar la instalación. Los proveedores de paquetes instalan OpenJDK como una dependencia de Tomcat, pero la biblioteca de conectores de MySQL debe instalarse de forma explícita.

1. Utiliza un [recurso de enlace](https://docs.chef.io/chef/resources.html#link) de Chef para crear un symlink en el directorio de bibliotecas del servidor Tomcat con la biblioteca de conectores de MySQL en el JDK.

   Utilizando los valores de los atributos predeterminados, el directorio de las bibliotecas de Tomcat es `/usr/share/tomcat6/lib` y la biblioteca de conectores de MySQL (`mysql-connector-java.jar`) está en `/usr/share/java/`.

La receta `tomcat::remove_root_webapp` elimina la aplicación web ROOT (`/var/lib/tomcat6/webapps/ROOT` de forma predeterminada) para evitar problemas de seguridad.

```
ruby_block 'remove the ROOT webapp' do
  block do
    ::FileUtils.rm_rf(::File.join(node['tomcat']['webapps_base_dir'], 'ROOT'), :secure => true)
  end
  only_if { ::File.exists?(::File.join(node['tomcat']['webapps_base_dir'], 'ROOT')) && !::File.symlink?(::File.join(node['tomcat']['webapps_base_dir'], 'ROOT')) }
end
```

La declaración `only_if` garantiza que la receta elimine el archivo únicamente si existe.

**nota**  
La versión de Tomcat se especifica mediante el atributo `['tomcat']['base_version']`, que está establecido en 6 en el archivo de atributos. Para instalar Tomcat 7, utilice los atributos de JSON personalizado que anulan el atributo. Solo tiene que [editar la configuración de la pila](workingstacks-edit.md) e introducir el siguiente JSON en el cuadro **Custom Chef JSON (JSON de Chef personalizado)** o añadirlo a otro JSON personalizado existente:  

```
{
  'tomcat' : {
    'base_version' : 7
  }
}
```
El atributo de JSON personalizado anula el atributo predeterminado y establece la versión de Tomcat en 7. Para obtener más información acerca de la anulación de atributos, consulte [Anulación de atributos](workingcookbook-attributes.md).

## tomcat::service
<a name="create-custom-setup-service"></a>

La receta `tomcat::service` crea la definición de servicio de Tomcat.

```
service 'tomcat' do
  service_name "tomcat#{node['tomcat']['base_version']}"

  case node[:platform]
  when 'centos', 'redhat', 'fedora', 'amazon'
    supports :restart => true, :reload => true, :status => true
  when 'debian', 'ubuntu'
    supports :restart => true, :reload => false, :status => true
  end

  action :nothing
end
```

La receta utiliza los [recursos de servicio](https://docs.chef.io/chef/resources.html#service) de Chef para especificar el nombre del servicio de Tomcat (tomcat6, de manera predeterminada) y establece el atributo `supports` para definir el modo en que Chef controla el reinicio, la recarga y los comandos de estado del servicio en los diferentes sistemas operativos.
+ `true` indica que Chef puede utilizar el script init u otro proveedor de servicios para ejecutar el comando.
+ `false` indica que Chef debe intentar ejecutar el comando por otros medios.

Observe que `action` está establecido en `:nothing`. Para cada evento del ciclo de vida, OpsWorks Stacks inicia una ejecución de [Chef para ejecutar](https://docs.chef.io/chef_client_overview.html#the-chef-client-run) el conjunto de recetas adecuado. El libro de recetas de Tomcat sigue el mismo patrón de hacer que una receta cree la definición del servicio, pero no reinicie el servicio. Otras recetas de la ejecución de Chef controlan el reinicio, normalmente incluyendo un comando `notifies` en los recursos `template` que se utilizan para crear los archivos de configuración. Las notificaciones resultan cómodas para reiniciar un servicio, ya que solo lo hacen si la configuración ha cambiado. Además, si una ejecución de Chef tiene varias notificaciones de reinicio de un servicio, Chef lo reinicia como máximo una vez. Esta práctica evita problemas que podrían producirse si se intenta reiniciar un servicio que no está totalmente operativo, una fuente común de errores en Tomcat.

 El servicio de Tomcat debe definirse para cualquier ejecución de Chef que utilice notificaciones de reinicio. Por lo tanto, `tomcat::service` viene incluido en varias recetas para garantizar que se defina el servicio con cada ejecución de Chef. Si una ejecución de Chef incluye varias instancias de `tomcat::service`, no se produce penalización alguna, ya que Chef garantiza que la receta se ejecute solo una vez por ejecución, independientemente del número de veces que esté incluida.

## tomcat::container\$1config
<a name="create-custom-setup-config"></a>

La receta `tomcat::container_config` crea los archivos de configuración a partir de los archivos de plantilla del libro de recetas.

```
include_recipe 'tomcat::service'

template 'tomcat environment configuration' do
  path ::File.join(node['tomcat']['system_env_dir'], "tomcat#{node['tomcat']['base_version']}")
  source 'tomcat_env_config.erb'
  owner 'root'
  group 'root'
  mode 0644
  backup false
  notifies :restart, resources(:service => 'tomcat')
end

template 'tomcat server configuration' do
  path ::File.join(node['tomcat']['catalina_base_dir'], 'server.xml')
  source 'server.xml.erb'
  owner 'root'
  group 'root'
  mode 0644
  backup false
  notifies :restart, resources(:service => 'tomcat')
end
```

La receta llama primero a `tomcat::service`, que define el servicio si es necesario. La mayor parte de la receta consiste en dos [recursos de plantilla](https://docs.chef.io/chef/resources.html#template), cada uno de los cuales crea un archivo de configuración a partir de uno de los archivos de plantilla del libro de recetas, establece las propiedades del archivo y notifica a Chef que reinicie el servicio.

### Archivo de configuración del entorno de Tomcat
<a name="create-custom-setup-config-env"></a>

El primer recurso `template` utiliza el archivo de plantilla `tomcat_env_config.erb` para crear un archivo de configuración del entorno de Tomcat que se utiliza para definir las variables de entorno, por ejemplo `JAVA_HOME`. El nombre de archivo predeterminado es el argumento del recurso `template`. `tomcat::container_config` utiliza un atributo `path` para anular el valor predeterminado y el nombre del archivo de configuración `/etc/sysconfig/tomcat6` (Amazon Linux) o `/etc/default/tomcat6` (Ubuntu). El recurso `template` también especifica el propietario, el grupo y la configuración de modo del archivo, e indica a Chef que no cree archivos de backup.

Si examina el código fuente, verá que existen tres versiones de `tomcat_env_config.erb`, cada una en un subdirectorio diferente del directorio `templates`. Los directorios `ubuntu` y `amazon` contienen las plantillas para sus respectivos sistemas operativos. La carpeta `default` contiene una plantilla ficticia con una única línea de comentario, que se utiliza solo si se intenta ejecutar esta receta en una instancia con un sistema operativo no admitido. La receta `tomcat::container_config` no precisa especificar qué `tomcat_env_config.erb` utilizar. Chef elige automáticamente el directorio adecuado para el sistema operativo de la instancia basándose en las reglas descritas en [Especificidad de archivos](http://docs.chef.io/templates.html#file-specificity).

Los archivos `tomcat_env_config.erb` de este ejemplo se componen, en gran parte, de comentarios. Para establecer otras variables de entorno, tan solo quite el comentario de las líneas correspondientes y proporcione sus valores de preferencia.

**nota**  
Cualquier opción de configuración que pueda cambiar debe definirse como un atributo, en lugar de estar codificada en la plantilla. De esta forma, no es necesario volver a escribir la plantilla para cambiar una opción de configuración, basta con anular el atributo.

La plantilla de Amazon Linux establece una variable de entorno únicamente, tal y como se muestra en el siguiente fragmento.

```
...
# Use JAVA_OPTS to set java.library.path for libtcnative.so
#JAVA_OPTS="-Djava.library.path=/usr/lib"

JAVA_OPTS="${JAVA_OPTS} <%= node['tomcat']['java_opts'] %>"

# What user should run tomcat
#TOMCAT_USER="tomcat"
...
```

Se puede utilizar JAVA\$1OPTS para especificar opciones de Java, por ejemplo, la ruta de la biblioteca. Si se usan los valores de atributo predeterminados, la plantilla no establece opciones de Java para Amazon Linux. Puede definir sus opciones de Java anulando el atributo `['tomcat']['java_opts']`, por ejemplo, usando atributos de JSON personalizado. Para ver un ejemplo, consulta [Creación de una pila](create-custom-stack.md#create-custom-stack-stack).

La plantilla de Ubuntu establece varias variables de entorno, como se muestra en el siguiente fragmento de la plantilla.

```
# Run Tomcat as this user ID. Not setting this or leaving it blank will use the
# default of tomcat<%= node['tomcat']['base_version'] %>.
TOMCAT<%= node['tomcat']['base_version'] %>_USER=tomcat<%= node['tomcat']['base_version'] %>
...
# Run Tomcat as this group ID. Not setting this or leaving it blank will use
# the default of tomcat<%= node['tomcat']['base_version'] %>.
TOMCAT<%= node['tomcat']['base_version'] %>_GROUP=tomcat<%= node['tomcat']['base_version'] %>
...
JAVA_OPTS="<%= node['tomcat']['java_opts'] %>"

<% if node['tomcat']['base_version'].to_i < 7 -%>
# Unset LC_ALL to prevent user environment executing the init script from
# influencing servlet behavior.  See Debian bug #645221
unset LC_ALL
<% end -%>
```

Si se usan los valores de atributo predeterminados, la plantilla establece las variables de entorno de Ubuntu de la siguiente manera:
+ `TOMCAT6_USER` y `TOMCAT6_GROUP`, que representan el usuario y grupo de Tomcat, están establecidos en `tomcat6`.

  Si establece ['tomcat'] ['base\$1version'] en `tomcat7`, los nombres de las variables se resuelven como `TOMCAT7_USER` y `TOMCAT7_GROUP`, y ambos se establecen en `tomcat7`.
+ `JAVA_OPTS` se establece en `-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC`:
  + Al establecer `-Djava.awt.headless` en `true` se informa al motor de gráficos que la instancia no tiene encabezado y no tiene una consola, para abordar así el comportamiento defectuoso de determinadas aplicaciones gráficas.
  + `-Xmx128m` garantiza que JVM tenga suficientes recursos de memoria, 128 MB en este ejemplo.
  + `-XX:+UseConcMarkSweepGC` especifica la recopilación simultánea de elementos no utilizados, lo que ayuda a limitar las pausas causadas por la recopilación.

    Para obtener más información, consulte: [Mejoras del recolector Concurrent Mark Sweep](http://docs.oracle.com/javase/6/docs/technotes/guides/vm/cms-6.html).
+ Si la versión de Tomcat es inferior a la 7, la plantilla no establece `LC_ALL` para abordar un error de Ubuntu.

**nota**  
Con los atributos predeterminados, algunas de estas variables de entorno se establecen sencillamente en sus valores predeterminados. No obstante, establecer de forma explícita las variables de entorno en atributos significa que puede definir atributos de JSON personalizado para anular los atributos predeterminados y proporcionar los valores personalizados. Para obtener más información acerca de la anulación de atributos, consulte [Anulación de atributos](workingcookbook-attributes.md).

Para ver los archivos de plantilla completos, consulte el [código fuente](https://github.com/amazonwebservices/opsworks-example-cookbooks/tree/master/tomcat).

### Archivo de configuración server.xml
<a name="create-custom-setup-config-server"></a>

El segundo `template` recurso se utiliza `server.xml.erb` para crear el [archivo `system.xml` de configuración](http://tomcat.apache.org/tomcat-7.0-doc/config/), que configura el contenedor. servlet/JSP `server.xml.erb`no contiene ninguna configuración específica del sistema operativo, por lo que se encuentra en el `template` subdirectorio del directorio. `default`

La plantilla utiliza la configuración estándar, pero puede crear un archivo `system.xml` para Tomcat 6 o Tomcat 7. Por ejemplo, el siguiente código de la sección del servidor de la plantilla configura los agentes de escucha adecuados para la versión especificada.

```
<% if node['tomcat']['base_version'].to_i > 6 -%>
  <!-- Security listener. Documentation at /docs/config/listeners.html
  <Listener className="org.apache.catalina.security.SecurityListener" />
  -->
<% end -%>
  <!--APR library loader. Documentation at /docs/apr.html -->
  <Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
  <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
  <Listener className="org.apache.catalina.core.JasperListener" />
  <!-- Prevent memory leaks due to use of particular java/javax APIs-->
  <Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<% if node['tomcat']['base_version'].to_i < 7 -%>
  <!-- JMX Support for the Tomcat server. Documentation at /docs/non-existent.html -->
  <Listener className="org.apache.catalina.mbeans.ServerLifecycleListener" />
<% end -%>
  <Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<% if node['tomcat']['base_version'].to_i > 6 -%>
  <Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<% end -%>
```

La plantilla utiliza atributos en lugar de configuración codificada, de manera que puede cambiar fácilmente la configuración con atributos de JSON personalizado. Por ejemplo:

```
<Connector port="<%= node['tomcat']['port'] %>" protocol="HTTP/1.1"
           connectionTimeout="20000"
           URIEncoding="<%= node['tomcat']['uri_encoding'] %>"
           redirectPort="<%= node['tomcat']['secure_port'] %>" />
```

Para obtener más información, consulte el [código fuente](https://github.com/amazonwebservices/opsworks-example-cookbooks/tree/master/tomcat).

## tomcat:: apache\$1tomcat\$1bind
<a name="create-custom-setup-bind"></a>

La receta `tomcat::apache_tomcat_bind` habilita el servidor Apache para que actúe como front-end de Tomcat, recibiendo las solicitudes entrantes y enviándolas a Tomcat para devolver después las respuestas al cliente. En este ejemplo se utiliza [mod\$1proxy](https://httpd.apache.org/docs/2.2/mod/mod_proxy.html) como proxy/gateway de Apache.

```
execute 'enable mod_proxy for apache-tomcat binding' do
  command '/usr/sbin/a2enmod proxy'
  not_if do
    ::File.symlink?(::File.join(node['apache']['dir'], 'mods-enabled', 'proxy.load')) || node['tomcat']['apache_tomcat_bind_mod'] !~ /\Aproxy/
  end
end

execute 'enable module for apache-tomcat binding' do
  command "/usr/sbin/a2enmod #{node['tomcat']['apache_tomcat_bind_mod']}"
  not_if {::File.symlink?(::File.join(node['apache']['dir'], 'mods-enabled', "#{node['tomcat']['apache_tomcat_bind_mod']}.load"))}
end

include_recipe 'apache2::service'

template 'tomcat thru apache binding' do
  path ::File.join(node['apache']['dir'], 'conf.d', node['tomcat']['apache_tomcat_bind_config'])
  source 'apache_tomcat_bind.conf.erb'
  owner 'root'
  group 'root'
  mode 0644
  backup false
  notifies :restart, resources(:service => 'apache2')
end
```

Para habilitar `mod_proxy`, debe habilitar el módulo `proxy` y un módulo basado en protocolo. Dispone de dos opciones para el módulo de protocolo: 
+ HTTP: `proxy_http`
+ [ JServ Protocolo Apache (AJP](http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html)): `proxy_ajp`

  AJP es un protocolo interno de Tomcat.

Ambos [recursos execute](https://docs.chef.io/chef/resources.html#execute) de la receta ejecutan el comando `a2enmod`, que habilita el módulo especificado para crear los symlinks requeridos:
+ El primer recurso `execute` habilita el módulo `proxy`.
+ El segundo recurso `execute` habilita el módulo de protocolo, que está establecido en `proxy_http` de forma predeterminada.

  Si prefiere utilizar AJP personalizado, puede definir JSON personalizado para anular el atributo `apache_tomcat_bind_mod` y establecerlo en `proxy_ajp`. 

La `apache2::service` receta es una receta integrada en OpsWorks Stacks que define el servicio Apache. Para obtener más información, consulta la [receta](https://github.com/aws/opsworks-cookbooks/blob/release-chef-11.4/apache2/recipes/service.rb) en el repositorio de OpsWorks Stacks GitHub . 

El recurso `template` utiliza `apache_tomcat_bind.conf.erb` para crear un archivo de configuración denominado `tomcat_bind.conf` de forma predeterminada. Coloca el archivo en el directorio `['apache']['dir']/.conf.d`. El atributo `['apache']['dir']` se define en el archivo de atributos `apache2` integrado y se establece de forma predeterminada en `/etc/httpd` (Amazon Linux) o `/etc/apache2` (Ubuntu). Si el recurso `template` crea o cambia el archivo de configuración, el comando `notifies` programa un reinicio del servicio de Apache.

```
<% if node['tomcat']['apache_tomcat_bind_mod'] == 'proxy_ajp' -%>
ProxyPass <%= node['tomcat']['apache_tomcat_bind_path'] %> ajp://localhost:<%= node['tomcat']['ajp_port'] %>/
ProxyPassReverse <%= node['tomcat']['apache_tomcat_bind_path'] %> ajp://localhost:<%= node['tomcat']['ajp_port'] %>/
<% else %>
ProxyPass <%= node['tomcat']['apache_tomcat_bind_path'] %> http://localhost:<%= node['tomcat']['port'] %>/
ProxyPassReverse <%= node['tomcat']['apache_tomcat_bind_path'] %> http://localhost:<%= node['tomcat']['port'] %>/
<% end -%>
```

La plantilla usa las [ProxyPassReverse](https://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypassreverse)directivas [ProxyPass](https://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypass)y para configurar el puerto que se usa para pasar el tráfico entre Apache y Tomcat. Dado que ambos servidores están en la misma instancia, pueden utilizar una dirección URL de localhost y ambos están establecidos de forma predeterminada en `http://localhost:8080`.

# Recetas de configuración
<a name="create-custom-configure"></a>

**importante**  
El AWS OpsWorks Stacks servicio llegó al final de su vida útil el 26 de mayo de 2024 y se ha desactivado tanto para los clientes nuevos como para los existentes. Recomendamos encarecidamente a los clientes que migren sus cargas de trabajo a otras soluciones lo antes posible. Si tienes preguntas sobre la migración, ponte en contacto con el AWS Support equipo en [AWS Re:post](https://repost.aws/) o a través de Premium [AWS Support](https://aws.amazon.com/support).

Las recetas de configuración se asignan al evento Configure [del ciclo de vida](workingcookbook-events.md), que se produce en todas las instancias de la pila siempre que una instancia entra o sale del estado online. Las recetas de configuración se usan para ajustar la configuración de una instancia para responder a posibles cambios, según corresponda. Cuando implemente una receta de configuración, tenga en cuenta que el cambio en la configuración de la pila podría involucrar a instancias que no tienen nada que ver con esta capa. La receta debe ser capaz de responder adecuadamente, lo que podría suponer no hacer nada en algunos casos.

## tomcat::configure
<a name="create-custom-configure-configure"></a>

La receta `tomcat::configure` se destina a un evento Configure del ciclo de vida de la capa.

```
include_recipe 'tomcat::context'
# Optional: Trigger a Tomcat restart in case of a configure event, if relevant
# settings in custom JSON have changed (e.g. java_opts/JAVA_OPTS):
#include_recipe 'tomcat::container_config'
```

La receta `tomcat::configure` es básicamente una metarreceta que ejecuta dos recetas dependientes.

1. La receta `tomcat::context` crea un archivo de configuración del contexto de la aplicación web.

   Este archivo configura los recursos de JDBC que las aplicaciones utilizan para comunicarse con la instancia de MySQL, tal y como se trata en la siguiente sección. La ejecución de esta receta en respuesta a un evento de configuración permite a la capa actualizar el archivo de configuración del contexto de la aplicación web, en caso de que la capa de base de datos haya cambiado.

1. La receta de configuración `tomcat::container_config` se ejecuta de nuevo para capturar los cambios en la configuración de los contenedores.

`include` para `tomcat::container_config` aparece comentado en este ejemplo. Si desea utilizar JSON personalizado para modificar la configuración de Tomcat, puede eliminar el comentario. Un evento Configure del ciclo de vida ejecuta, a continuación, `tomcat::container_config`, que actualiza los archivos de configuración relacionados con Tomcat, tal y como se describe en [tomcat::container\$1config](create-custom-setup.md#create-custom-setup-config), y reinicia el servicio de Tomcat.

## tomcat::context
<a name="create-custom-configure-context"></a>

El recetario de Tomcat permite a las aplicaciones acceder a un servidor de bases de datos MySQL, que se puede ejecutar en una instancia independiente, mediante un objeto [ DataSourceJ2EE](http://docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html). Con Tomcat, puede activar la conexión creando e instalando un archivo de configuración del contexto de la aplicación web por cada aplicación. Este archivo define la relación entre la aplicación y el recurso JDBC que la aplicación utilizará para comunicarse con la base de datos. Para obtener más información, consulte [The Context Container](http://tomcat.apache.org/tomcat-7.0-doc/config/context.html).

El principal objetivo de la receta `tomcat::context` es crear este archivo de configuración.

```
include_recipe 'tomcat::service'

node[:deploy].each do |application, deploy|
  context_name = deploy[:document_root].blank? ? application : deploy[:document_root]

  template "context file for #{application} (context name: #{context_name})" do
    path ::File.join(node['tomcat']['catalina_base_dir'], 'Catalina', 'localhost', "#{context_name}.xml")
    source 'webapp_context.xml.erb'
    owner node['tomcat']['user']
    group node['tomcat']['group']
    mode 0640
    backup false
    only_if { node['datasources'][context_name] }
    variables(:resource_name => node['datasources'][context_name], :webapp_name => application)
    notifies :restart, resources(:service => 'tomcat')
  end
end
```

Además de los atributos del recetario de Tomcat, esta receta utiliza los atributos de [configuración e implementación de la pila que OpsWorks Stacks instala con el evento](workingcookbook-json.md) Configure. El servicio OpsWorks Stacks agrega atributos al objeto de nodo de cada instancia que contienen la información que las recetas suelen obtener mediante bolsas de datos o búsquedas, e instala los atributos en cada instancia. Los atributos contienen información detallada sobre la configuración de la pila, las aplicaciones implementadas y aquellos datos personalizados que un usuario quiera incluir. Las recetas pueden obtener datos de los atributos de configuración e implementación de la pila utilizando la sintaxis de nodo de Chef estándar. Para obtener más información, consulte [Atributos de configuración e implementación de pilas](workingcookbook-json.md). Con las pilas de Chef 11.10, también puede utilizar la búsqueda de Chef para obtener los datos de configuración e implementación de la pila. Para obtener más información, consulte [Uso de la búsqueda de Chef](workingcookbook-chef11-10.md#workingcookbook-chef11-10-search).

`deploy`los atributos hacen referencia al espacio de `[:deploy]` nombres, que contiene los atributos relacionados con la implementación que se definen a través de la consola o la API, o que se generan mediante el servicio Stacks. OpsWorks El atributo `deploy` incluye un atributo por cada aplicación implementada, cuyo nombre es el nombre abreviado de la aplicación. Cada atributo de aplicación contiene un conjunto de atributos que caracterizan la aplicación, por ejemplo, la raíz de documentos (`[:deploy][:appname][:document_root]`).

La receta `context` garantiza, en primer lugar, que el servicio se defina para esta ejecución de Chef llamando a [tomcat::service](create-custom-setup.md#create-custom-setup-service). A continuación, define una variable `context_name` que representa el nombre del archivo de configuración, sin la extensión `.xml`. Si utiliza la raíz de documentos de forma predeterminada, `context_name` se establece en el nombre abreviado de la aplicación. De lo contrario, se establece en la raíz de documentos especificada. En el ejemplo tratado en [Crear una pila y ejecutar una aplicación](create-custom-stack.md) se establece la raíz de documentos en `"ROOT"`, de manera que el contexto es ROOT y el archivo de configuración se llama `ROOT.xml`.

La mayor parte de la receta recorre la lista de aplicaciones implementadas y utiliza con cada una la plantilla `webapp_context.xml.erb` para crear un archivo de configuración de contexto. En el ejemplo se implementa una única aplicación, pero la definición del atributo `deploy` requiere que se trate como una lista de aplicaciones independientemente.

La plantilla `webapp_context.xml.erb` no contiene ningún valor de configuración específico del sistema operativo, por lo que se encuentra en el subdirectorio `templates` del directorio `default`.

La receta crea el archivo de configuración de la manera siguiente:
+ Si se usan los valores de atributo predeterminados, el nombre de archivo de configuración se establece en `context_name.xml` y se instala en el directorio `/etc/tomcat6/Catalina/localhost/`. 

  El nodo `['datasources']` de los atributos de configuración de la pila contiene uno o varios atributos, cada uno de los cuales asigna un nombre de contexto a los recursos de datos JDBC que la aplicación asociada va a utilizar para comunicarse con la base de datos. El nodo y su contenido se definen con JSON personalizado cuando se crea la pila, tal y como se describe más adelante en [Crear una pila y ejecutar una aplicación](create-custom-stack.md). El ejemplo tiene un único atributo que asocia el nombre de contexto ROOT con un recurso JDBC llamado jdbc/mydb.
+ Si se usan los valores de atributo predeterminados, el usuario y el grupo del archivo se establecen en los valores que se definen en el paquete de Tomcat: `tomcat` (Amazon Linux) o `tomcat6` (Ubuntu).
+ El recurso `template` crea el archivo de configuración solo si existe el nodo `['datasources']` e incluye un atributo `context_name`.
+ El recurso `template` define dos variables, `resource_name` y `webapp_name`.

  `resource_name` está establecido en el nombre del recurso que se asocia con `context_name`, y `webapp_name` está establecido en el nombre abreviado de la aplicación.
+ El recurso de plantilla reinicia el servicio de Tomcat para cargar y activar los cambios.

La plantilla `webapp_context.xml.erb` se compone de un elemento `Context` que contiene un elemento `Resource` con su propio conjunto de atributos.

Estos atributos `Resource` caracterizan la configuración del contexto:
+ **name**: el nombre del recurso de JDBC, que se establece en el valor `resource_name` definido en `tomcat::context`.

  En el ejemplo, el nombre del recurso está establecido en jdbc/mydb.
+ **auth** y **tipo**: estos son valores de configuración estándar para las conexiones `DataSource` de JDBC.
+ **maxActive**, **maxIdle** y **maxWait**: el número máximo de conexiones activas e inactivas, y el tiempo máximo de espera hasta que se devuelve una conexión.
+ **username** y **password**: la contraseña raíz y el nombre del usuario de la base de datos, que se obtienen de los atributos `deploy`.
+ **driverClassName**—El nombre de la clase del controlador JDBC, que se establece en el controlador MySQL.
+ **url**: la URL de conexión.

  El prefijo depende de la base de datos. Debe establecerse en `jdbc:mysql` para MySQL, `jdbc:postgresql` para Postgres, y en `jdbc:sqlserver` para SQL Server. En el ejemplo se establece la dirección URL en `jdbc:mysql://host_IP_Address:3306:simplejsp`, donde *simplejsp* es el nombre abreviado de la aplicación.
+ **factory**: el generador `DataSource`, necesario en las bases de datos MySQL.

[Para obtener más información sobre este archivo de configuración, consulte el tema Uso de la wiki de Tomcat. DataSources](http://wiki.apache.org/tomcat/UsingDataSources)

# Recetas de implementación
<a name="create-custom-deploy"></a>

**importante**  
El AWS OpsWorks Stacks servicio llegó al final de su vida útil el 26 de mayo de 2024 y se ha desactivado tanto para los clientes nuevos como para los existentes. Recomendamos encarecidamente a los clientes que migren sus cargas de trabajo a otras soluciones lo antes posible. Si tienes preguntas sobre la migración, ponte en contacto con el AWS Support equipo en [AWS Re:post](https://repost.aws/) o a través de Premium [AWS Support](https://aws.amazon.com/support).

Las recetas de implementación se asignan al evento Deploy del [ciclo de vida](workingcookbook-events.md) de la capa. Suele ocurrir en todas las instancias de la pila cada vez que despliegas una aplicación, aunque, si lo deseas, puedes restringir el evento solo a instancias específicas. OpsWorks Stacks también ejecuta las recetas de implementación en instancias nuevas, una vez completadas las recetas de configuración. El objetivo principal de las recetas de implementación es implementar el código y los archivos relacionados de un repositorio en las instancias de la capa del servidor de aplicaciones. Sin embargo, a menudo se ejecutan también en otras capas. Esto permite que las instancias de esas capas, por ejemplo, actualicen su configuración para adaptarse a la nueva aplicación implementada. Cuando implemente una receta de implementación, tenga en cuenta que un evento Deploy no supone necesariamente que las aplicaciones se implementen en la instancia. Podría simplemente ser una notificación para que las aplicaciones se implementen en otras instancias de la pila, para permitir que la instancia haga las actualizaciones que sean necesarias. La receta debe ser capaz de responder de forma adecuada, lo que podría significar no hacer nada.

OpsWorks Stacks implementa automáticamente las aplicaciones de los tipos de aplicaciones estándar en las correspondientes capas del servidor de aplicaciones integradas. Para implementar una capa personalizada, debe implementar las recetas de implementación personalizadas que descargan los archivos de la aplicación de un repositorio en la ubicación adecuada de la instancia. No obstante, a menudo podrá limitar la cantidad de código que debe escribir utilizando [el libro de recetas de implementación](https://github.com/aws/opsworks-cookbooks/tree/release-chef-11.4/deploy) integrado para controlar algunos aspectos de la implementación. Por ejemplo, si almacena los archivos en uno de los repositorios compatibles, el libro de recetas integrado puede controlar los detalles de la descarga de los archivos del repositorio en las instancias de la capa. 

La receta `tomcat::deploy` debe asignarse al evento Deploy del ciclo de vida.

```
include_recipe 'deploy'

node[:deploy].each do |application, deploy|
  opsworks_deploy_dir do
    user deploy[:user]
    group deploy[:group]
    path deploy[:deploy_to]
  end

  opsworks_deploy do
    deploy_data deploy
    app application
  end
...
```

La receta `tomcat::deploy` utiliza el libro de recetas de implementación integrado para aspectos de implementación que no son específicos de la aplicación. La receta `deploy` (que es la forma abreviada de la receta integrada `deploy::default`) es una receta integrada que administra los detalles de configuración de los usuarios, los grupos, etc., en función de los datos de los atributos `deploy`.

La receta utiliza dos definiciones de Chef integradas, `opsworks_deploy_dir` y `opworks_deploy`, para instalar la aplicación. 

La definición `opsworks_deploy_dir` configura la estructura de directorios en función de los datos del JSON de implementación de la aplicación. Las definiciones son básicamente una cómoda forma de empaquetar las definiciones de los recursos y se encuentran en el directorio `definitions` de un libro de recetas. Las recetas pueden utilizar definiciones de forma similar a los recursos, pero la definición por sí misma no tiene un proveedor asociado, solo los recursos incluidos en ella. Puede definir variables en la receta, que se pasan a las definiciones de los recursos subyacentes. La receta `tomcat::deploy` establece las variables `user`, `group` y `path` según los datos del JSON de implementación. Se pasan al [recurso de directorios](https://docs.chef.io/chef/resources.html#directory) de la definición, que administra los directorios. 

**nota**  
El usuario y el grupo de su aplicación implementada vienen determinados por los atributos `[:opsworks][:deploy_user][:user]` y `[:opsworks][:deploy_user][:group]`, que se definen en el [archivo de atributos `deploy.rb` del libro de recetas de implementación integrado](https://github.com/aws/opsworks-cookbooks/blob/release-chef-11.4/deploy/attributes/deploy.rb). El valor predeterminado de `[:opsworks][:deploy_user][:user]` es `deploy`. El valor predeterminado de `[:opsworks][:deploy_user][:group]` depende del sistema operativo de la instancia:  
Para las instancias de Ubuntu, el grupo predeterminado es `www-data`.
Para las instancias de Amazon Linux que pertenecen a una capa del servidor de aplicaciones de Rails que usa Nginx y Unicorn, el grupo predeterminado es `nginx`.
Para todas las demás instancias de Amazon Linux, el grupo predeterminado es `apache`.
Puede cambiar cualquier valor utilizando JSON personalizado o un archivo de atributos personalizados para anular el atributo correspondiente. Para obtener más información, consulte [Anulación de atributos](workingcookbook-attributes.md).

La otra definición, `opsworks_deploy`, administra los detalles de la comprobación de código y los archivos relacionados de la aplicación del repositorio y los implementa en la instancia, en función de los datos de los atributos `deploy`. Puede utilizar esta definición con cualquier tipo de aplicación; los detalles de implementación como, por ejemplo, los nombres de directorio, se especifican en la consola o a través de la API, y se incluyen en los atributos `deploy`. No obstante, `opsworks_deploy` funciona únicamente con los cuatro [tipos de repositorio admitidos](workingcookbook-installingcustom-repo.md): Git, Subversion, S3 y HTTP. Debe implementar este código manualmente si desea utilizar otro tipo de repositorio.

Puede instalar los archivos de una aplicación en el directorio `webapps` de Tomcat. Una práctica habitual es copiar los archivos directamente en `webapps`. Sin embargo, la implementación de OpsWorks Stack está diseñada para conservar hasta cinco versiones de una aplicación en una instancia, por lo que puedes volver a una versión anterior si es necesario. OpsWorks Por lo tanto, Stacks hace lo siguiente:

1. Implementa las aplicaciones en un directorio distinto cuyo nombre contiene una marca temporal, como `/srv/www/my_1st_jsp/releases/20130731141527`.

1. Crea un symlink llamado `current`, como `/srv/www/my_1st_jsp/current`, en este directorio único.

1. Si no existe, crea un symlink desde el directorio `webapps` en el symlink `current` creado en el paso 2.

Si necesita volver a una versión anterior, modifique el symlink `current` para que apunte a un directorio distinto que contenga la marca temporal adecuada, por ejemplo, cambiando el destino del enlace de `/srv/www/my_1st_jsp/current`.

La sección central de `tomcat::deploy` configura el symlink. 

```
  ...
  current_dir = ::File.join(deploy[:deploy_to], 'current')
  webapp_dir = ::File.join(node['tomcat']['webapps_base_dir'], deploy[:document_root].blank? ? application : deploy[:document_root])

  # opsworks_deploy creates some stub dirs, which are not needed for typical webapps
  ruby_block "remove unnecessary directory entries in #{current_dir}" do
    block do
      node['tomcat']['webapps_dir_entries_to_delete'].each do |dir_entry|
        ::FileUtils.rm_rf(::File.join(current_dir, dir_entry), :secure => true)
      end
    end
  end

  link webapp_dir do
    to current_dir
    action :create
  end
  ...
```

La primera receta crea dos variables, `current_dir` y `webapp_dir` para representar los directorios `current` y `webapp`, respectivamente. A continuación, utiliza un recurso `link` para vincular `webapp_dir` con `current_dir`. La `deploy::default` receta de OpsWorks Stacks crea algunos directorios auxiliares que no son necesarios para este ejemplo, por lo que la parte central del extracto los elimina.

La parte final de `tomcat::deploy` reinicia el servicio de Tomcat, si es necesario.

```
  ...
  include_recipe 'tomcat::service'

  execute 'trigger tomcat service restart' do
    command '/bin/true'
    not_if { node['tomcat']['auto_deploy'].to_s == 'true' }
    notifies :restart, resources(:service => 'tomcat')
  end
end

include_recipe 'tomcat::context'
```

La receta ejecuta en primer lugar `tomcat::service` para garantizar que el servicio se defina para esta ejecución de Chef. Después, utiliza un [recurso execute](https://docs.chef.io/chef/resources.html#execute) para notificar al servicio el reinicio, pero solo si `['tomcat']['auto_deploy']` se establece en `'true'`. De lo contrario, Tomcat permanece a la escucha de posibles cambios en su directorio `webapps`, lo que hace innecesario reiniciar un servicio de Tomcat explícito . 

**nota**  
El recurso `execute` no ejecuta nada realmente sustancial; `/bin/true` es un script de shell ficticio que simplemente devuelve un código de éxito. Se utiliza aquí como una forma cómoda de generar una notificación de reinicio. Como se ha mencionado anteriormente, la utilización de las notificaciones garantiza que los servicios no se reinicien con demasiada frecuencia.

Por último, `tomcat::deploy` ejecuta `tomcat::context`, que actualiza el archivo de configuración de contexto de la aplicación web si ha cambiado la base de datos de back-end. 

# Crear una pila y ejecutar una aplicación
<a name="create-custom-stack"></a>

**importante**  
El AWS OpsWorks Stacks servicio llegó al final de su vida útil el 26 de mayo de 2024 y se ha desactivado tanto para los clientes nuevos como para los existentes. Recomendamos encarecidamente a los clientes que migren sus cargas de trabajo a otras soluciones lo antes posible. Si tienes preguntas sobre la migración, ponte en contacto con el AWS Support equipo en [AWS Re:post](https://repost.aws/) o a través de Premium [AWS Support](https://aws.amazon.com/support).

En esta sección se muestra cómo utilizar el libro de recetas de Tomcat para implementar una instalación de pila básica que ejecuta una sencilla aplicación de páginas de servidor Java (JSP) denominada SimpleJSP. La pila consta de una capa personalizada basada en Tomcat denominada TomCustom y una capa MySQL. SimpleJSP se despliega en la base de datos MySQL TomCustom y muestra cierta información de ella. Si aún no estás familiarizado con los conceptos básicos de cómo usar OpsWorks Stacks, deberías leer primero. [Introducción a las pilas de Linux en Chef 11](gettingstarted.md)

## La aplicación SimpleJSP
<a name="create-custom-stack-jsp"></a>

La aplicación SimpleJSP muestra los aspectos básicos de la configuración de una conexión de base de datos y la recuperación de datos de la base de datos MySQL de la pila.

```
<html>
  <head>
    <title>DB Access</title>
  </head>
  <body>
    <%@ page language="java" import="java.sql.*,javax.naming.*,javax.sql.*" %>
    <%
      StringBuffer output = new StringBuffer();
      DataSource ds = null;
      Connection con = null;
      Statement stmt = null;
      ResultSet rs = null;
      try {
        Context initCtx = new InitialContext();
        ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/mydb");
        con = ds.getConnection();
        output.append("Databases found:<br>");
        stmt = con.createStatement();
        rs = stmt.executeQuery("show databases");
        while (rs.next()) {
          output.append(rs.getString(1));
          output.append("<br>");
        }
      }
      catch (Exception e) {
        output.append("Exception: ");
        output.append(e.getMessage());
        output.append("<br>");
      }
      finally {
        try {
          if (rs != null) {
            rs.close();
          }
          if (stmt != null) {
            stmt.close();
          }
          if (con != null) {
            con.close();
          }
        }
        catch (Exception e) {
          output.append("Exception (during close of connection): ");
          output.append(e.getMessage());
          output.append("<br>");
        }
      }
    %>
    <%= output.toString() %>
  </body>
</html>
```

SimpleJSP utiliza un objeto `DataSource` para comunicarse con la base de datos MySQL. Tomcat utiliza los datos del [archivo de configuración de contexto de la aplicación web](create-custom-configure.md#create-custom-configure-context) para crear e inicializar un objeto `DataSource` y enlazarlo a un nombre lógico. A continuación, registra el nombre lógico con un servicio de nomenclatura JNDI (interfaz de directorios y nomenclatura de Java). Para obtener una instancia del objeto `DataSource` adecuado, debe crear un objeto `InitialContext` y pasar el nombre lógico del recurso al método `lookup` del objeto, que recupera el objeto adecuado. El nombre lógico del ejemplo SimpleJSP, `java:comp/env/jdbc/mydb`, presenta los siguientes componentes:
+ El espacio de nombres raíz, `java`, que se separa del resto del nombre por medio de dos puntos (:). 
+ Cualquier otro espacio de nombres adicional, separado por barras (/).

  Tomcat añade automáticamente recursos al espacio de nombres `comp/env`.
+ El nombre del recurso, que se define en el archivo de configuración de contexto de la aplicación web y se separa del espacio de nombres con una barra.

  El nombre del recurso en este ejemplo es `jdbc/mydb`. 

Para establecer una conexión con la base de datos, SimpleJSP hace lo siguiente:

1. Abre el método `DataSource` del objeto `getConnection`, que devuelve un objeto `Connection`.

1. Llama al método `Connection` del objeto `createStatement` para crear un objeto `Statement`, que se utiliza para comunicarse con la base de datos.

1. Se comunica con la base de datos llamando al método `Statement` adecuado.

   SimpleJSP llama a `executeQuery` para ejecutar una consulta SHOW DATABASES que enumera las bases de datos del servidor.

El método `executeQuery` devuelve un objeto `ResultSet`, que contiene los resultados de la consulta. SimpleJSP obtiene los nombres de la base de datos del objeto devuelto `ResultSet` y los concatena para crear una cadena de salida. Por último, el ejemplo cierra los objetos `ResultSet`, `Statement` y `Connection`. Para obtener más información sobre JSP y JDBC, consulta [JavaServer Pages Technology](http://docs.oracle.com/javaee/5/tutorial/doc/bnagx.html) y [JDBC](http://docs.oracle.com/javase/tutorial/jdbc/basics/) Basics, respectivamente.

Para utilizar SimpleJSP con una pila, debe colocarla en un repositorio. Puede utilizar cualquiera de los repositorios admitidos, pero para usar SimpleJSP con la pila de ejemplo tratada en la siguiente sección, debe ponerla en un archivo de S3 público. Para obtener más información acerca de cómo utilizar el resto de repositorios estándar, consulte [Repositorios de libros de recetas](workingcookbook-installingcustom-repo.md).

**Para poner SimpleJSP en un repositorio de archivos de S3**

1. Copie el código de ejemplo en un archivo llamado `simplejsp.jsp` y ponga el archivo en un directorio llamado `simplejsp`.

1. Cree un archivo `.zip` del directorio `simplejsp`.

1. Cree un bucket de Amazon S3 público, cargue `simplejsp.zip` en el bucket y haga el archivo público.

   Para obtener una descripción de cómo realizar esta tarea, consulte [Comenzar a utilizar Amazon Simple Storage Service](https://docs.aws.amazon.com/AmazonS3/latest/gsg/GetStartedWithS3.html).

## Creación de una pila
<a name="create-custom-stack-stack"></a>

Para ejecutar SimpleJSP, necesita una pila con las siguientes capas.
+ Una capa MySQL que sea compatible con el servidor back-end de MySQL.
+ Una capa personalizada que utilice el libro de recetas de Tomcat para admitir las instancias del servidor Tomcat.

**Para crear la pila**

1. En el panel de OpsWorks Stacks, haz clic en **Añadir pila para crear una pila** nueva y haz clic en **Avanzado** >> para ver todas las opciones. Configure la pila del modo siguiente.
   + **Nombre**: un nombre de pila definido por el usuario; en este ejemplo se utiliza. TomStack
   + **Usar libros de recetas personalizados de Chef**: establezca la alternancia en **Sí** para mostrar algunas opciones adicionales.
   + **Tipo de repositorio**: Git.
   + **URL de repositorio** - `git://github.com/amazonwebservices/opsworks-example-cookbooks.git`.
   + **JSON de Chef personalizado**: añada el JSON siguiente

     ```
     {
       "tomcat": {
         "base_version": 7,
         "java_opts": "-Djava.awt.headless=true -Xmx256m"
       },
       "datasources": {
         "ROOT": "jdbc/mydb"
       }
     }
     ```

   Para el resto de opciones, puede aceptar los valores predeterminados.

   El JSON personalizado hace lo siguiente:
   + Anula el atributo `['base_version']` del libro de recetas de Tomcat para establecer la versión de Tomcat en 7; el valor predeterminado es 6.
   + Anula el atributo `['java_opts']` del libro de recetas de Tomcat para especificar que la instancia no tiene encabezado y define el tamaño del montón de JVM máximo en 256 MB; el valor predeterminado no establece opciones para las instancias que ejecutan Amazon Linux.
   + Especifica el valor del atributo `['datasources]`, que asigna un nombre de recurso de JDBC (jdbc/mydb) al nombre del contexto de la aplicación web (ROOT), como se ha visto en [tomcat::context](create-custom-configure.md#create-custom-configure-context).

     Este último atributo no tiene ningún valor predeterminado; debe establecerlo con JSON personalizado.  
![\[Configuration Management interface showing Chef version options and custom JSON input field.\]](http://docs.aws.amazon.com/es_es/opsworks/latest/userguide/images/tom_add_stack.png)

1. Haga clic en **Add a layer (Añadir una capa)**. En **Layer type (Tipo de capa)**, seleccione **MySQL**. Después, haga clic en **Add Layer (Añadir capa)**.

1. Haga clic en **Instances (Instancias)** en el panel de navegación y, a continuación, haga clic en **Add an instance (Añadir una instancia)**. Haga clic en **Add Instance (Añadir una instancia)** para aceptar la configuración predeterminada. En la línea de la instancia, haga clic en **start (iniciar)**.

1. Vuelva a la página **Layers (Capas)** y haga clic en **\$1 Layer (\$1 Capa)** para añadir una capa. En **Layer type (Tipo de capa)**, haga clic en **Custom (Personalizado)**. En el ejemplo se utiliza **TomCustom** y **tomcustom** como nombre y nombre abreviado de la capa, respectivamente.  
![\[Add Layer form with Custom layer type, Name, and Short name fields for creating a customized layer.\]](http://docs.aws.amazon.com/es_es/opsworks/latest/userguide/images/tom_add_custom_layer.png)

1. En la página **Layers (Capas)**, para la capa personalizada, haga clic en **Recipes (Recetas)** y, a continuación, haga clic en **Edit (Editar)**. En **Custom Chef Recipes (Recetas Chef personalizadas)**, asigne las recetas del libro de recetas de Tomcat a los eventos de ciclo de vida de la capa, como se indica a continuación:
   + Para **Setup (Configurar)**, escriba **tomcat::setup** y haga clic en **\$1**.
   + Para **Configura (Configurar)**, escriba **tomcat::configure** y haga clic en **\$1**.
   + Para **Deploy**, escriba **tomcat::deploy** y haga clic en **\$1**. Después, haga clic en **Save (Guardar)**.

     .  
![\[Custom Chef Recipes interface showing setup, configure, and deploy steps with options.\]](http://docs.aws.amazon.com/es_es/opsworks/latest/userguide/images/tom_events.png)

1. Haga clic en **Apps (Aplicaciones)** en el panel de navegación y, a continuación, haga clic en **Add an app (Añadir una aplicación)**. Especifique las siguientes opciones y, a continuación, haga clic en **Add App (Añadir aplicación)**:
   + **Nombre: el nombre** de la aplicación; en el ejemplo se usa SimpleJSP y el nombre abreviado generado por OpsWorks Stacks será simplejsp.
   + **Tipo de app**: establezca esta opción en **Otro**.

     OpsWorks Stacks implementa automáticamente los tipos de aplicaciones estándar en las instancias de servidor asociadas. Si establece **App type (Tipo de aplicación)** en other, OpsWorks Stacks simplemente ejecuta las recetas de implementación y les permite controlar la implementación.
   + **Raíz del documento**: establezca esta opción en **ROOT**.

     El valor de **Document root (Raíz del documento)** especifica el nombre del contexto.
   + **Tipo de repositorio**: establezca esta opción en **S3 Archive**.
   + **URL de repositorio**: establezca esta opción en la URL de Amazon S3 de la aplicación que ha creado anteriormente.

   Utilice la configuración predeterminada para el resto de las opciones.  
![\[Application settings form with fields for name, app type, document root, and source details.\]](http://docs.aws.amazon.com/es_es/opsworks/latest/userguide/images/tom_app.png)

1. Usa la página **Instancias** para agregar una instancia a la TomCustom capa e iniciarla. OpsWorks Stacks ejecuta automáticamente las recetas de implementación en una nueva instancia una vez completadas las recetas de configuración, por lo que al iniciar la instancia también se implementa SimpleJSP.

1. Cuando la TomCustom instancia esté en línea, haz clic en el nombre de la instancia en la página **Instancias** para ver sus detalles. Copie la dirección IP pública. A continuación, cree una URL de la siguiente manera: http://*publicIP**appname.jsp*/tc/. Por ejemplo, la URL tendrá un aspecto similar a **http://50.218.191.172/tc/simplejsp.jsp**.
**nota**  
La URL de Apache que reenvía las solicitudes a Tomcat está establecida en el atributo predeterminado de `['tomcat']['apache_tomcat_bind_path']`, `/tc/`. La raíz de documentos de SimpleJSP se establece en `ROOT`, que es un valor especial que se resuelve como `/`. Por tanto, la dirección URL es "... /tc/simplejsp.jsp".

1. Pegue la dirección URL del paso anterior en el navegador. Debería ver lo siguiente:

   ```
   Databases found:
   information_schema
   simplejsp
   test
   ```
**nota**  
Si tu pila tiene una instancia de MySQL, OpsWorks Stacks crea automáticamente una base de datos para cada aplicación, nombrada con el nombre abreviado de la aplicación.