

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Criação de uma camada de servidor Tomcat personalizada
<a name="create-custom"></a>

**Importante**  
O AWS OpsWorks Stacks serviço chegou ao fim da vida útil em 26 de maio de 2024 e foi desativado para clientes novos e existentes. É altamente recomendável que os clientes migrem suas cargas de trabalho para outras soluções o mais rápido possível. Se você tiver dúvidas sobre migração, entre em contato com a AWS Support equipe no [AWS re:POST](https://repost.aws/) ou por meio do Premium [AWS Support](https://aws.amazon.com/support).

**nota**  
Este tópico descreve como implementar uma camada personalizada para uma pilha do Linux. No entanto, os princípios básicos e parte do código também podem ser adaptados para implementar camadas personalizadas para pilhas do Windows, especialmente aquelas na seção sobre implantação de aplicações.

A maneira mais simples de usar pacotes não padrão em instâncias do OpsWorks Stacks é [estender uma camada existente](workingcookbook-extend-package.md). No entanto, essa abordagem instala e executa os pacotes padrão e não padrão nas instâncias da camada, o que nem sempre é desejável. Uma abordagem um pouco mais exigente, mas mais eficiente, é implementar uma camada personalizada, que oferece a você um controle quase completo sobre as instâncias da camada, inclusive o seguinte: 
+ Quais pacotes são instalados
+ Como cada pacote está configurado
+ Como implantar aplicações de um repositório na instância

Independentemente de usar o console ou a API, você cria e gerencia uma camada personalizada da mesma maneira que qualquer outra camada, conforme descrito em [Camadas personalizadas](workinglayers-custom.md). No entanto, as receitas integradas de uma camada personalizada realizam apenas algumas tarefas bem básicas, como instalar um cliente do Ganglia para relatar métricas a um mestre do Ganglia. Para deixar as instâncias de uma camada personalizada mais do que minimamente funcionais, você deve implementar um ou mais livros de receitas personalizados com receitas do Chef e arquivos relacionados para processar as tarefas de instalação e configuração de pacotes, implantação de aplicações etc. Porém, você não precisa necessariamente implementar tudo do zero. Por exemplo, se armazenar aplicações em um dos repositórios padrão, você poderá usar as receitas de implantação integradas para processar boa parte do trabalho de instalação das aplicações nas instâncias da camada.

**nota**  
Se você ainda não conhece o Chef, primeiro deverá ler [Introdução a livros de receitas](cookbooks-101.md), que é um tutorial que apresenta as noções básicas de como implementar os livros de receitas para realizar uma variedade de tarefas comuns. 

O passo a passo a seguir descreve como implementar uma camada personalizada que dê suporte a um servidor de aplicações Tomcat. A camada se baseia em um livro de receitas personalizado chamado Tomcat, que inclui receitas para processar a instalação de pacotes, a implantação etc. O passo a passo inclui trechos do livro de receitas Tomcat. Você pode baixar o livro de receitas completo em seu [GitHub repositório](https://github.com/amazonwebservices/opsworks-example-cookbooks/tree/master/tomcat). Caso não esteja familiarizado com [Opscode Chef](http://www.opscode.com/chef/), você deve ler primeiramente [Livros de receitas e receitas](workingcookbook.md).

**nota**  
OpsWorks O Stacks inclui uma [camada completa do Java App Server para uso](layers-java.md) em produção. A finalidade do livro de receitas do Tomcat é mostrar como implementar camadas personalizadas, de maneira que ele só dê suporte a uma versão limitada do Tomcat que não inclui recursos como SSL. Para obter um exemplo de uma implementação com todos os recursos, consulte o livro de receitas [opsworks\$1java](https://github.com/aws/opsworks-cookbooks/tree/release-chef-11.10/opsworks_java) integrado.

O livro de receitas do Tomcat dá suporte a uma camada personalizada cujas instâncias têm as seguintes características:
+ Elas dão suporte a um servidor de aplicações Java Tomcat com um front-end do Apache.
+ O Tomcat é configurado para permitir que aplicações usem um objeto `DataSource` JDBC para se conectar a uma instância MySQL à parte, que funciona como um armazenamento de dados back-end.

O livro de receitas deste projeto envolve vários componentes principais:
+ [Arquivo de atributos](create-custom-attributes.md) contém definições de configuração usadas por várias receitas.
+ [Receitas de instalação](create-custom-setup.md) são atribuídas ao [evento do ciclo de vida](workingcookbook-events.md) de configuração da camada. Eles serão executados depois que uma instância tiver sido inicializada e realizarão tarefas como a instalação de pacotes e a criação de arquivos de configuração.
+ [Receitas de configuração](create-custom-configure.md) são atribuídas ao evento do ciclo de vida de configuração da camada. Elas serão executadas depois das alterações de configuração da pilha, principalmente quando as instâncias ficam on-line ou off-line, e processarão todas as alterações obrigatórias feitas na configuração.
+ [Receitas de implantação](create-custom-deploy.md) são atribuídas ao evento do ciclo de vida de implantação da camada. Elas serão executadas depois das receitas de instalação e quando você implantar manualmente uma aplicação para instalar o código e os arquivos relacionados nas instâncias de camada e processar tarefas relacionadas, como reiniciar serviços.

A seção final, [Criar uma pilha e executar uma aplicação](create-custom-stack.md), descreve como criar uma pilha que inclua uma camada personalizada com base no livro de receitas do Tomcat e como implantar e executar uma aplicação JSP simples que exiba dados de um banco de dados do MySQL em execução em uma instância que pertença a uma camada MySQL separada.

**nota**  
As receitas do livro de receitas do Tomcat dependem de algumas receitas integradas do OpsWorks Stacks. Para esclarecer a origem de cada receita, este tópico identifica receitas que usam a convenção *nome\$1do\$1livro\$1de\$1receitas*::*nome\$1da\$1receita* do Chef.

**Topics**
+ [Arquivo de atributos](create-custom-attributes.md)
+ [Receitas de instalação](create-custom-setup.md)
+ [Receitas de configuração](create-custom-configure.md)
+ [Receitas de implantação](create-custom-deploy.md)
+ [Criar uma pilha e executar uma aplicação](create-custom-stack.md)

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

**Importante**  
O AWS OpsWorks Stacks serviço chegou ao fim da vida útil em 26 de maio de 2024 e foi desativado para clientes novos e existentes. É altamente recomendável que os clientes migrem suas cargas de trabalho para outras soluções o mais rápido possível. Se você tiver dúvidas sobre migração, entre em contato com a AWS Support equipe no [AWS re:POST](https://repost.aws/) ou por meio do Premium [AWS Support](https://aws.amazon.com/support).

Antes de observar as receitas, será útil examinar primeiramente o arquivo de atributos do livro de receitas do Tomcat, que contém várias definições de configuração usadas pelas receitas. Os atributos não são obrigatórios. Você pode simplesmente codificar esses valores nas receitas ou nos modelos. No entanto, se você definir as configurações usando atributos, poderá usar o console ou a API do OpsWorks Stacks para modificar os valores definindo atributos JSON personalizados, o que é mais simples e flexível do que reescrever a receita ou o código do modelo sempre que quiser alterar uma configuração. Essa abordagem permite, por exemplo, usar o mesmo livro de receitas para várias pilhas, mas configurar o servidor Tomcat de maneira diferente para cada pilha. Para obter mais informações sobre atributos e como substitui-los, consulte [Sobrepor atributos](workingcookbook-attributes.md).

O exemplo a seguir mostra o arquivo de atributos completo, `default.rb`, localizado no diretório `attributes` do livro de receitas do 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
```

As configurações propriamente ditas serão abordadas depois na seção relacionada. As seguintes observações normalmente se aplicam:
+ Como todas as definições de nó são do tipo `default`, você pode substituí-las por [atributos JSON personalizados](workingcookbook-json-override.md).
+ O arquivo usa uma instrução `case` para definir condicionalmente alguns valores de atributo com base no sistema operacional da instância.

  O nó `platform` é gerado pela ferramenta Ohai do Chef e representa o sistema operacional da instância. 

# Receitas de instalação
<a name="create-custom-setup"></a>

**Importante**  
O AWS OpsWorks Stacks serviço chegou ao fim da vida útil em 26 de maio de 2024 e foi desativado para clientes novos e existentes. É altamente recomendável que os clientes migrem suas cargas de trabalho para outras soluções o mais rápido possível. Se você tiver dúvidas sobre migração, entre em contato com a AWS Support equipe no [AWS re:POST](https://repost.aws/) ou por meio do Premium [AWS Support](https://aws.amazon.com/support).

As receitas de instalação são atribuídas ao evento do [ciclo de vida](workingcookbook-events.md) de configuração da camada e executadas após a inicialização de uma instância. Elas realizam tarefas como instalar pacotes, criar arquivos de configuração e iniciar serviços. Depois que as receitas de configuração terminarem de ser OpsWorks executadas, o Stacks executa [as receitas](create-custom-deploy.md) de implantação para implantar qualquer aplicativo na nova instância.

**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>

A receita `tomcat::setup` deve ser atribuída a um evento do ciclo de vida de configuração de uma camada.

```
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'
```

A receita `tomcat::setup` é mais uma metarreceita. Ela inclui um conjunto de receitas dependentes que processam a maioria dos detalhes de como instalar e configurar o Tomcat e os pacotes relacionados. A primeira parte do `tomcat::setup` executa as seguintes receitas, que serão abordadas posteriormente: 
+ A receita [tomcat::install](#create-custom-setup-install) instala o pacote do servidor Tomcat.
+ A receita [tomcat::service](#create-custom-setup-service) configura o serviço Tomcat.

A parte intermediária de `tomcat::setup` habilita e inicia o serviço Tomcat:
+ O [service resource](https://docs.chef.io/chef/resources.html#service) do Chef habilita o serviço Tomcat na inicialização.
+ O [bash resource](https://docs.chef.io/chef/resources.html#bash) do Chef executa um script Bash para iniciar o daemon autofs, necessário para instâncias com suporte do Amazon EBS. O recurso acaba notificando o recurso `service` para reiniciar o serviço Tomcat.

  Para obter mais informações, 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) ou [Autofs](https://help.ubuntu.com/community/Autofs) (para Ubuntu).

A parte final de `tomcat::setup` cria arquivos de configuração, além de instalar e configurar o servidor Apache front-end:
+ A receita [tomcat::container\$1config](#create-custom-setup-config) cria arquivos de configuração.
+ A `apache2` receita (que é uma abreviatura de`apache2::default`) é uma receita integrada do OpsWorks Stacks que instala e configura um servidor Apache.
+ A receita [tomcat::apache\$1tomcat\$1bind](#create-custom-setup-bind) configura o servidor Apache para funcionar como um front-end para o servidor Tomcat.

**nota**  
Muitas vezes, você pode economizar tempo e esforço usando receitas integradas para realizar algumas das tarefas obrigatórias. Esta receita usa a receita `apache2::default` integrada para instalar o Apache, em vez de implementá-lo do zero. Para obter outro exemplo de como usar receitas integradas, consulte [Receitas de implantação](create-custom-deploy.md).

As seções a seguir descrevem as receitas de instalação do livro de receitas Tomcat em mais detalhes. Para obter mais informações sobre as receitas `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>

A receita `tomcat::install ` instala o servidor Tomcat, o OpenJDK e uma biblioteca de conectores Java que processa a conexão com o 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'
```

A receita executa as seguintes tarefas:

1. Cria uma lista de pacotes a serem instalados, dependendo do sistema operacional da instância.

1. Instala cada pacote na lista.

   O [package resource](https://docs.chef.io/chef/resources.html#id146) do Chef usa o provedor apropriado (`yum` para Amazon Linux e `apt-get` para Ubuntu) a fim de processar a instalação. Os provedores de pacotes instalam o OpenJDK como uma dependência do Tomcat, mas a biblioteca de conectores MySQL deve ser instalada explicitamente.

1. Usa um recurso [link resource](https://docs.chef.io/chef/resources.html#link) do Chef para criar um symlink no diretório lib do servidor do Tomcat para o a biblioteca de conectores do MySQL no JDK.

   Usando os valores de atributo padrão, o diretório lib do Tomcat é `/usr/share/tomcat6/lib` e a biblioteca de conectores do MySQL (`mysql-connector-java.jar`) está em `/usr/share/java/`.

A receita `tomcat::remove_root_webapp` remove o aplicativo web ROOT (`/var/lib/tomcat6/webapps/ROOT` por padrão) para evitar alguns problemas de segurança.

```
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
```

A instrução `only_if` garante que a receita só remova o arquivo caso ele exista.

**nota**  
A versão do Tomcat é especificada pelo atributo `['tomcat']['base_version']`, definido como 6 no arquivo de atributos. Para instalar o Tomcat 7, você pode usar atributos JSON personalizados para substituir o atributo. Basta [editar as configurações da pilha](workingstacks-edit.md) e inserir o seguinte JSON na caixa **Custom Chef JSON** ou adicioná-la a qualquer JSON personalizado existente:  

```
{
  'tomcat' : {
    'base_version' : 7
  }
}
```
O atributo JSON personalizado substitui o atributo padrão e define a versão do Tomcat como 7. Para obter mais informações sobre como substituir esses atributos, consulte [Sobrepor atributos](workingcookbook-attributes.md).

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

A receita `tomcat::service` cria a definição de serviço do 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
```

A receita usa o [service resource](https://docs.chef.io/chef/resources.html#service) do Chef para especificar o nome do serviço do Tomcat (tomcat6, por padrão) e define o atributo `supports` para determinar como o Chef gerencia os comandos de reinicialização, recarregamento e status do serviço nos sistemas operacionais diferentes.
+ `true` indica que o Chef pode usar o script init ou outro provedor de serviços para executar o comando
+ `false` indica que o Chef deve tentar executar o comando por outros meios.

O `action` é definido como `:nothing`. Para cada evento do ciclo de vida, o OpsWorks Stacks inicia uma execução do [Chef para executar](https://docs.chef.io/chef_client_overview.html#the-chef-client-run) o conjunto apropriado de receitas. O livro de receitas do Tomcat segue um padrão comum de fazer uma receita criar a definição de serviço, mas não reiniciá-lo. Outras receitas na execução do Chef processam a reinicialização, normalmente incluindo um comando `notifies` nos recursos `template` usados para criar arquivos de configuração. Notificações são uma maneira prática de reiniciar um serviço porque elas só fazem isso caso a configuração tenha sido alterada. Além disso, caso uma execução do Chef tenha várias notificações de reinicialização para um serviço, o Chef reinicia o serviço uma vez, no máximo. Essa prática evita problemas que possam ocorrer durante a tentativa de reiniciar um serviço que não esteja totalmente operacional, que é uma fonte comum de erros do Tomcat.

 O serviço Tomcat deve ser definidos para qualquer execução do Chef que use notificações de reinicialização. Portanto, `tomcat::service` é incluído em vários receitas, para garantir que o serviço seja definido para cada execução do Chef. Não haverá penalidade se uma execução do Chef incluir várias instâncias de `tomcat::service` porque o Chef garante que uma receita seja executada somente uma vez por execução, independentemente de quantas vezes ele seja incluído.

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

A receita `tomcat::container_config` cria arquivos de configuração com base em arquivos de modelo do livro de receitas.

```
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
```

A receita chama primeiro `tomcat::service`, que define o serviço, se necessário. A maior parte da receita consiste em dois [template resources](https://docs.chef.io/chef/resources.html#template), cada um criando um arquivo de configuração com base em um dos arquivos de modelo do livro de receitas, define as propriedades do arquivo e notifica o Chef para reiniciar o serviço.

### Arquivo de configuração do ambiente do Tomcat
<a name="create-custom-setup-config-env"></a>

O primeiro recurso `template` usa o arquivo de modelo `tomcat_env_config.erb` para criar um arquivo de configuração do ambiente do Tomcat, usado para definir variáveis do ambiente, como `JAVA_HOME`. O nome do arquivo padrão é o argumento do recurso `template`. `tomcat::container_config` usa um atributo `path` para substituir o valor padrão e o nome do arquivo de configuração `/etc/sysconfig/tomcat6` (Amazon Linux) ou `/etc/default/tomcat6` (Ubuntu). O recurso `template` também especifica o proprietário, o grupo e as configurações de modo do arquivo e leva o Chef a não criar arquivos de backup.

Caso você observe o código-fonte, na verdade, há três versões de `tomcat_env_config.erb`, cada uma em um subdiretório diferente do diretório `templates`. Os diretórios `ubuntu` e `amazon` contêm os modelos para os respectivos sistemas operacionais. A pasta `default` contém um modelo fictício com uma única linha de comentário, usada apenas caso você tente executar essa receita em uma instância com um sistema operacional não compatível. A receita `tomcat::container_config` não precisa especificar qual `tomcat_env_config.erb` usar. O Chef escolhe automaticamente o diretório apropriado para o sistema operacional da instância com base em regras descritas em [File Specificity](http://docs.chef.io/templates.html#file-specificity).

Os arquivos `tomcat_env_config.erb` deste exemplo consistem em grande parte de comentários. Para definir variáveis de ambiente adicionais, basta excluir o comentário das linhas apropriadas e fornecer os valores preferidos.

**nota**  
Qualquer definição de configuração que possa mudar deve ser determinada como um atributo, em vez de codificada no modelo. Assim, você não precisa reescrever o modelo para alterar uma configuração, bastando substituir o atributo.

O modelo do Amazon Linux define apenas uma variável de ambiente, conforme mostrado no trecho a seguir.

```
...
# 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"
...
```

JAVA\$1OPTS pode ser usado para especificar opções de Java, como o caminho da biblioteca. Usando os valores de atributo padrão, o modelo não define opções de Java para o Amazon Linux. Você pode definir as próprias opções de Java substituindo o atributo `['tomcat']['java_opts']`, por exemplo, usando atributos JSON personalizados. Para ver um exemplo, consulte [Criar um stack](create-custom-stack.md#create-custom-stack-stack).

O modelo do Ubuntu define várias variáveis de ambiente, conforme mostrado no trecho do modelo a seguir.

```
# 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 -%>
```

Usando valores de atributo padrão, o modelo define as variáveis de ambiente do Ubuntu da seguinte forma:
+ `TOMCAT6_USER` e `TOMCAT6_GROUP`, que representam o usuário e o grupo do Tomcat, são definidos como `tomcat6`.

  Caso você defina ['tomcat'] ['base\$1version'] como `tomcat7`, os nomes de variável são resolvidos como `TOMCAT7_USER` e `TOMCAT7_GROUP`, e ambos são definidos como `tomcat7`.
+ `JAVA_OPTS` é definido como `-Djava.awt.headless=true -Xmx128m -XX:+UseConcMarkSweepGC`:
  + A definição de `-Djava.awt.headless` como `true` informa o mecanismo de gráficos que a instância é descentralizada e não tem um console, o que resolve o comportamento de determinadas aplicações gráficas.
  + `-Xmx128m` garante que o JVM tenha recursos de memória adequados, 128 MB para este exemplo.
  + `-XX:+UseConcMarkSweepGC` especifica a coleta de lixo de varredura de marca simultânea, o que ajuda a limitar pausas induzidas pela coleta de lixo.

    Para obter mais informações, consulte: [Concurrent Mark Sweep Collector Enhancements](http://docs.oracle.com/javase/6/docs/technotes/guides/vm/cms-6.html).
+ Caso a versão do Tomcat seja inferior à versão 7, o modelo cancela a definição de `LC_ALL`, que resolve um bug do Ubuntu.

**nota**  
Com os atributos padrão, algumas dessas variáveis de ambiente são simplesmente definidas como os valores padrão. No entanto, a definição explícita das variáveis de ambiente como atributos significa que você pode definir atributos JSON personalizados para substituir os atributos padrão e fornecer valores personalizados. Para obter mais informações sobre como substituir esses atributos, consulte [Sobrepor atributos](workingcookbook-attributes.md).

Para obter os arquivos de modelo completos, consulte o [source code](https://github.com/amazonwebservices/opsworks-example-cookbooks/tree/master/tomcat).

### Arquivo de configuração Server.xml
<a name="create-custom-setup-config-server"></a>

O segundo `template` recurso é usado `server.xml.erb` para criar o [arquivo `system.xml` de configuração](http://tomcat.apache.org/tomcat-7.0-doc/config/), que configura o servlet/JSP contêiner. `server.xml.erb`não contém configurações específicas do sistema operacional, portanto, está no `template` subdiretório do `default` diretório.

O modelo usa configurações padrão, mas pode criar um arquivo `system.xml` para o Tomcat 6 ou o Tomcat 7. Por exemplo, o código a seguir na seção do servidor do modelo configura as escutas corretamente para a versão 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 -%>
```

O modelo usa atributos em vez de configurações codificadas, de maneira que você possa alterar facilmente as configurações definindo atributos JSON personalizados. Por exemplo:

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

Para obter mais informações, consulte o [source code](https://github.com/amazonwebservices/opsworks-example-cookbooks/tree/master/tomcat).

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

A receita `tomcat::apache_tomcat_bind` permite que o servidor Apache funcione como o front-end do Tomcat, recebendo solicitações de entrada e as encaminhando para o Tomcat e retornando as respostas ao cliente. Este exemplo usa [mod\$1proxy](https://httpd.apache.org/docs/2.2/mod/mod_proxy.html) como o proxy/gateway do 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`, você deve habilitar o módulo `proxy` e um módulo com base em protocolo. Você tem duas opções para o módulo de protocolo: 
+ HTTP: `proxy_http`
+ [ JServ Protocolo Apache](http://tomcat.apache.org/connectors-doc/ajp/ajpv13a.html) (AJP): `proxy_ajp`

  AJP é um protocolo do Tomcat interno.

Os [execute resources](https://docs.chef.io/chef/resources.html#execute) da receita executam o comando `a2enmod`, que habilita o módulo especificado criando os symlinks obrigatórios:
+ O primeiro recurso `execute` habilita o módulo `proxy`.
+ O segundo recurso `execute` habilita o módulo de protocolo, definido como `proxy_http`, por padrão.

  Caso prefira usar AJP, você pode definir JSON personalizada para substituir o atributo `apache_tomcat_bind_mod` e defini-lo como `proxy_ajp`. 

A `apache2::service` receita é uma receita integrada do OpsWorks Stacks que define o serviço Apache. Para obter mais informações, consulte a [receita](https://github.com/aws/opsworks-cookbooks/blob/release-chef-11.4/apache2/recipes/service.rb) no GitHub repositório OpsWorks Stacks. 

O recurso `template` usa `apache_tomcat_bind.conf.erb` para criar um arquivo de configuração que, por padrão, é chamado `tomcat_bind.conf`. Ele salva o arquivo no diretório `['apache']['dir']/.conf.d`. O atributo `['apache']['dir']` é definido no arquivo de atributos `apache2` integrados, e é definido por padrão como `/etc/httpd` (Amazon Linux) ou `/etc/apache2` (Ubuntu). Caso o recurso `template` crie ou altere o arquivo de configuração, o comando `notifies` programa uma reinicialização do serviço do 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 -%>
```

O modelo usa as [ProxyPassReverse](https://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypassreverse)diretivas [ProxyPass](https://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxypass)e para configurar a porta usada para transmitir tráfego entre o Apache e o Tomcat. Como ambos os servidores estão na mesma instância, eles podem usar um URL localhost e são definidos por padrão como `http://localhost:8080`.

# Receitas de configuração
<a name="create-custom-configure"></a>

**Importante**  
O AWS OpsWorks Stacks serviço chegou ao fim da vida útil em 26 de maio de 2024 e foi desativado para clientes novos e existentes. É altamente recomendável que os clientes migrem suas cargas de trabalho para outras soluções o mais rápido possível. Se você tiver dúvidas sobre migração, entre em contato com a AWS Support equipe no [AWS re:POST](https://repost.aws/) ou por meio do Premium [AWS Support](https://aws.amazon.com/support).

As receitas de configuração são atribuídas ao evento do [ciclo de vida](workingcookbook-events.md) de configuração da camada, que ocorre em todas as instâncias da pilha sempre que uma instância entra ou sai do estado online. Você usa receitas de configuração a fim de ajustar a configuração de uma instância para responder à alteração, conforme apropriado. Ao implementar uma receita de configuração, lembre-se de que uma alteração feita na configuração da pilha pode envolver instâncias que não têm nada a ver com essa camada. A receita deve ser capaz de responder devidamente, o que pode significar não fazer nada em alguns casos.

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

A receita `tomcat::configure` se destina a um evento do ciclo de vida de configuração da camada.

```
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'
```

A receita `tomcat::configure` é basicamente uma metarreceita que executa duas receitas dependentes.

1. A receita `tomcat::context` cria um arquivo de configuração de contexto da aplicação da web.

   Este arquivo configura os recursos JDBC usados pelas aplicações para se comunicar com a instância do MySQL, conforme abordado na próxima seção. A execução dessa receita em resposta a um evento de configuração permite que a camada atualize o arquivo de configuração de contexto da aplicação da web caso a camada do banco de dados tenha sido alterada.

1. A receita de configuração `tomcat::container_config` é reexecutada para capturar eventuais alterações feitas na configuração do contêiner.

O `include` de `tomcat::container_config` é comentado neste exemplo. Caso queira usar o JSON personalizado para modificar as configurações do Tomcat, você pode remover o comentário. Um evento do ciclo de vida de configuração acaba executando `tomcat::container_config`, que atualiza os arquivos de configuração relacionados ao Tomcat, conforme descrito em [tomcat::container\$1config](create-custom-setup.md#create-custom-setup-config) e reinicia o serviço Tomcat.

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

[O livro de receitas do Tomcat permite que os aplicativos acessem um servidor de banco de dados MySQL, que pode ser executado em uma instância separada, usando um objeto J2EE. DataSource](http://docs.oracle.com/javase/tutorial/jdbc/basics/sqldatasources.html) Com o Tomcat, você pode habilitar a conexão criando e instalando um arquivo de configuração de contexto da aplicação da web para cada aplicação. Este arquivo define a relação entre a aplicação e o recurso JDBC que a aplicação usará para se comunicar com o banco de dados. Para obter mais informações, consulte [The Context Container](http://tomcat.apache.org/tomcat-7.0-doc/config/context.html).

A finalidade principal da receita `tomcat::context` é criar esse arquivo de configuração.

```
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
```

Além dos atributos do livro de receitas do Tomcat, essa receita usa os atributos de [configuração e implantação da pilha](workingcookbook-json.md) que o OpsWorks Stacks instala com o evento Configure. O serviço OpsWorks Stacks adiciona atributos ao objeto de nó de cada instância que contêm as informações que as receitas normalmente obteriam usando pacotes de dados ou pesquisas e instala os atributos em cada instância. Os atributos contêm informações detalhadas sobre a configuração da pilha, as aplicações implantadas e eventuais dados personalizados que um usuário deseja incluir. As receitas podem obter dados dos atributos de configuração e implantação da pilha usando a sintaxe de nó do Chef padrão. Para obter mais informações, consulte [Configuração de pilha e atributos de implantação](workingcookbook-json.md). Com as pilhas do Chef 11.10, você também pode usar o Chef para obter os dados configuração e implantação da pilha. Para obter mais informações, consulte [Utilização da pesquisa do Chef](workingcookbook-chef11-10.md#workingcookbook-chef11-10-search).

`deploy`attributes se refere ao `[:deploy]` namespace, que contém atributos relacionados à implantação que são definidos por meio do console ou da API ou gerados pelo serviço Stacks. OpsWorks O atributo `deploy` inclui um atributo para cada aplicação implantada, com o nome abreviado da aplicação. Cada atributo da aplicação contém um conjunto de atributos que caracterizam a aplicação, como a raiz do documento (`[:deploy][:appname][:document_root]`).

A receita `context` primeiro garante que o serviço seja definido para esta execução do Chef chamando [tomcat::service](create-custom-setup.md#create-custom-setup-service). Em seguida, ele define uma variável `context_name` que representa o nome do arquivo de configuração, excluindo a extensão `.xml`. Caso você use a raiz do documento padrão, `context_name` é definido como o nome abreviado da aplicação. Do contrário, ele é definido como a raiz do documento especificada. O exemplo abordado em [Criar uma pilha e executar uma aplicação](create-custom-stack.md) define a raiz do documento como `"ROOT"`, de maneira que o contexto seja ROOT e o arquivo de configuração se chame `ROOT.xml`.

A maior parte da receita passa pela lista de aplicações implantadas e, para cada aplicação, usa o modelo `webapp_context.xml.erb` para criar um arquivo de configuração. O exemplo implanta apenas uma aplicação, mas a definição do atributo `deploy` exige que você o trate como uma lista de aplicações independentemente disso.

O modelo `webapp_context.xml.erb` não é específico para sistema operacional, por isso está localizado no subdiretório `templates`, no diretório `default`.

A receita cria o arquivo de configuração da seguinte forma:
+ Usando-se valores de atributo padrão, o nome do arquivo de configuração é definido como `context_name.xml` e instalado no diretório `/etc/tomcat6/Catalina/localhost/`. 

  O nó `['datasources']` dos atributos de configuração da pilha contém um ou mais atributos, cada um mapeando um nome de contexto para o recurso de dados JDBC que a aplicação associada usará para se comunicar com o banco de dados. O nó e o conteúdo são definidos com o JSON personalizado quando você cria a pilha, conforme descrito posteriormente em [Criar uma pilha e executar uma aplicação](create-custom-stack.md). O exemplo tem um único atributo que associa o nome de contexto ROOT a um recurso JDBC chamado jdbc/mydb.
+ Usando valores de atributo padrão, o usuário do arquivo e o grupo são definidos como os valores definidos pelo pacote do Tomcat: `tomcat` (Amazon Linux) ou `tomcat6` (Ubuntu).
+ O recurso `template` só cria o arquivo de configuração caso o nó `['datasources']` exista e inclui um atributo `context_name`.
+ O recurso `template` define duas variáveis, `resource_name` e `webapp_name`.

  `resource_name` é definido como o nome do recurso associado a `context_name` e `webapp_name` é definido como o nome abreviado da aplicação.
+ O recurso do modelo reinicia o serviço Tomcat para carregar e ativar as alterações.

O modelo `webapp_context.xml.erb` consiste em um elemento `Context` que contém um elemento `Resource` com o próprio conjunto de atributos.

Os atributos `Resource` caracterizam a configuração do contexto:
+ **name**: o nome do recurso JDBC, definido como o valor `resource_name` definido em `tomcat::context`.

  Por exemplo, o nome do recurso é definido como jdbc/mydb.
+ **auth** e **type**: estas são configurações padrão para conexões JDBC `DataSource`.
+ **maxActive**, **maxIdle** e **maxWait**: o número máximo de conexões ativas e inativas, e o tempo de espera máximo para uma conexão ser retornada.
+ **username** e **password**: o nome de usuário e a senha raiz do banco de dados, obtidos junto aos atributos `deploy`.
+ **driverClassName**— O nome da classe do driver JDBC, que é definido como o driver MySQL.
+ **url**: a conexão URL.

  O prefixo depende do banco de dados. Ele deve ser definido como `jdbc:mysql` para MySQL, `jdbc:postgresql` para Postgres e `jdbc:sqlserver` para SQL Server. O exemplo define o URL como `jdbc:mysql://host_IP_Address:3306:simplejsp`, em que *simplejsp* é o nome abreviado da aplicação.
+ **factory**: a fábrica `DataSource`, obrigatória para bancos de dados MySQL.

Para obter mais informações sobre esse arquivo de configuração, consulte o DataSources tópico [Usando](http://wiki.apache.org/tomcat/UsingDataSources) no wiki do Tomcat.

# Receitas de implantação
<a name="create-custom-deploy"></a>

**Importante**  
O AWS OpsWorks Stacks serviço chegou ao fim da vida útil em 26 de maio de 2024 e foi desativado para clientes novos e existentes. É altamente recomendável que os clientes migrem suas cargas de trabalho para outras soluções o mais rápido possível. Se você tiver dúvidas sobre migração, entre em contato com a AWS Support equipe no [AWS re:POST](https://repost.aws/) ou por meio do Premium [AWS Support](https://aws.amazon.com/support).

As receitas de implantação são atribuídas ao evento do [ciclo de vida](workingcookbook-events.md) de implantação da camada. Normalmente, ocorre em todas as instâncias da pilha sempre que você implanta um aplicativo, embora você possa, opcionalmente, restringir o evento somente a instâncias especificadas. OpsWorks O Stacks também executa as receitas de implantação em novas instâncias, após a conclusão das receitas de configuração. A finalidade principal das receitas de implantação é implantar código e arquivos relacionados de um repositório nas instâncias da camada do servidor de aplicações. No entanto, você normalmente executa receitas de implantação em outras camadas também. Isso permite que as instâncias dessas camadas, por exemplo, atualizem a configuração para acomodar a aplicação recém-implantada. Quando você implementar uma receita de implantação, lembre-se de que um evento de implantação não necessariamente significa que aplicações estejam sendo implantadas na instância. Pode ser simplesmente uma notificação de que aplicações estão sendo implantadas em outras instâncias na pilha para permitir que a instância faça eventuais atualizações necessárias. A receita deve ser capaz de responder adequadamente, o que pode significar não fazer nada.

OpsWorks O Stacks implanta automaticamente aplicativos dos tipos de aplicativos padrão nas camadas correspondentes do servidor de aplicativos incorporado. Para implantar aplicações em uma camada personalizada, você deve implementar receitas de implantação personalizadas que fazem download dos arquivos da aplicação de um repositório no local apropriado na instância. No entanto, você normalmente pode limitar a quantidade de código que deve gravar usando [deploy cookbook](https://github.com/aws/opsworks-cookbooks/tree/release-chef-11.4/deploy) integrada para lidar com alguns aspectos da implantação. Por exemplo, caso você armazene os arquivos em um dos repositórios compatíveis, o livro de receitas integrado pode processar os detalhes do download dos arquivos do repositório para as instâncias da camada. 

A receita `tomcat::deploy` deve ser atribuída ao evento do ciclo de vida de implementação.

```
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
...
```

A receita `tomcat::deploy` usa o livro de receitas de implantação integrado em aspectos da implantação que não sejam específicos da aplicação. A receita `deploy` (abreviada para a receita `deploy::default` integrada) é uma receita integrada que processa os detalhes da configuração de usuários, grupos etc., com base em dados dos atributos `deploy`.

A receita usa duas definições do Chef integradas `opsworks_deploy_dir` e `opworks_deploy` para instalar a aplicação. 

A definição `opsworks_deploy_dir` configura a estrutura do diretório, com base em dados do JSON de implantação da aplicação. As definições são basicamente uma maneira prática de empacotar definições de recurso e estão localizadas no diretório `definitions` de um livro de receitas. As receitas podem usar definições como os recursos, mas a definição propriamente dita não tem um provedor associado, apenas os recursos incluídos na definição. Você pode definir variáveis na receita, que são passadas para as definições de recurso subjacentes. A receita `tomcat::deploy` define variáveis `user`, `group` e `path` com base em dados do JSON de implantação. Eles são passados para o [directory resource](https://docs.chef.io/chef/resources.html#directory) da definição, que gerencia os diretórios. 

**nota**  
O usuário e o grupo da aplicação implantado são determinados pelos atributos `[:opsworks][:deploy_user][:user]` e `[:opsworks][:deploy_user][:group]`, definidos no [arquivo de atributos `deploy.rb` do livro de receitas de implantação integrado](https://github.com/aws/opsworks-cookbooks/blob/release-chef-11.4/deploy/attributes/deploy.rb). O valor padrão de `[:opsworks][:deploy_user][:user]` é `deploy`. O valor padrão de `[:opsworks][:deploy_user][:group]` depende do sistema operacional da instância:  
Para instâncias do Ubuntu, o grupo padrão é `www-data`.
Para instâncias do Amazon Linux membros de uma camada do Rails App Server que use Nginx e Unicorn, o grupo padrão é `nginx`.
Para todas as outras instâncias do Amazon Linux, o grupo padrão é `apache`.
Você pode alterar a definição usando um JSON personalizado ou um arquivo de atributos personalizado para substituir o atributo apropriado. Para obter mais informações, consulte [Sobrepor atributos](workingcookbook-attributes.md).

A outra definição, `opsworks_deploy`, processa os detalhes de verificação do código da aplicação e dos arquivos relacionados do repositório e os implanta na instância, com base em dados dos atributos `deploy`. Você pode usar essa definição para qualquer tipo de aplicação; detalhes da implantação, como os nomes de diretório especificados no console ou por meio da API e colocar os atributos `deploy`. No entanto, `opsworks_deploy` só funciona para os quatro [tipos de repositório compatíveis](workingcookbook-installingcustom-repo.md): Git, Subversion, S3 e HTTP. Você deve implementar esse código sozinho caso queira usar um tipo de repositório diferente.

Você instala os arquivos de uma aplicação no diretório `webapps` do Tomcat. Uma prática comum é copiar os arquivos diretamente para `webapps`. No entanto, a implantação do OpsWorks Stacks foi projetada para reter até cinco versões de um aplicativo em uma instância, para que você possa reverter para uma versão anterior, se necessário. OpsWorks Portanto, o Stacks faz o seguinte:

1. Implanta aplicativos em um diretório distinto cujo nome contém um time stamp, como `/srv/www/my_1st_jsp/releases/20130731141527`.

1. Cria um symlink chamado `current`, como `/srv/www/my_1st_jsp/current`, para esse diretório exclusivo.

1. Caso ele ainda não exista, cria um symlink com base no diretório `webapps` para o symlink `current` criado na Etapa 2.

Caso você precise reverter para uma versão anterior, modifique o symlink `current` a fim de apontar para um diretório distinto que contenha o carimbo de data e hora apropriado, por exemplo, alterando o link de destino de `/srv/www/my_1st_jsp/current`.

A seção intermediária de `tomcat::deploy` configura o 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
  ...
```

A receita cria primeiramente duas variáveis, `current_dir` e `webapp_dir`, para representar os diretórios `current` e `webapp`, respectivamente. Em seguida, ele usa um recurso `link` para vincular `webapp_dir` a `current_dir`. A `deploy::default` receita do OpsWorks Stacks cria alguns diretórios stub que não são necessários para este exemplo, então a parte central do trecho os remove.

A parte final de `tomcat::deploy` reinicia o serviço do Tomcat, se necessário.

```
  ...
  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'
```

A receita executa primeiramente `tomcat::service` a fim de garantir que o serviço seja definido para essa execução do Chef. Ela acaba usando um [execute resource](https://docs.chef.io/chef/resources.html#execute) a fim de notificar o serviço para reiniciar, mas somente se `['tomcat']['auto_deploy']` for definido como `'true'`. Do contrário, o Tomcat escuta alterações no diretório `webapps`, que torna uma reinicialização do serviço do Tomcat explícito desnecessário. 

**nota**  
O recurso `execute` não executa realmente nada substantivo; `/bin/true` é um script do shell fictício que simplesmente retorna um código de êxito. Ele é usado aqui apenas como uma maneira cômoda para gerar uma notificação de reinicialização. Conforme mencionado anteriormente, o uso de notificações garante que os serviços não sejam reiniciados com muita frequência.

Por fim, `tomcat::deploy` executa `tomcat::context`, que atualiza o arquivo de configuração do contexto da aplicação da web caso você tenha alterado o banco de dados back-end. 

# Criar uma pilha e executar uma aplicação
<a name="create-custom-stack"></a>

**Importante**  
O AWS OpsWorks Stacks serviço chegou ao fim da vida útil em 26 de maio de 2024 e foi desativado para clientes novos e existentes. É altamente recomendável que os clientes migrem suas cargas de trabalho para outras soluções o mais rápido possível. Se você tiver dúvidas sobre migração, entre em contato com a AWS Support equipe no [AWS re:POST](https://repost.aws/) ou por meio do Premium [AWS Support](https://aws.amazon.com/support).

Esta seção mostra como usar o livro de receitas do Tomcat para implementar uma configuração de pilha básica que execute uma aplicação JSP simples chamada SimpleJSP. A pilha consiste em uma camada personalizada baseada em Tomcat chamada e TomCustom uma camada MySQL. O SimpleJSP é implantado TomCustom e exibe algumas informações do banco de dados MySQL. Se você ainda não está familiarizado com o básico de como usar o OpsWorks Stacks, leia primeiro. [Conceitos básicos das pilhas Linux do Chef 11](gettingstarted.md)

## A aplicação SimpleJSP
<a name="create-custom-stack-jsp"></a>

A aplicação SimpleJSP demonstra os conceitos básicos de como configurar uma conexão de banco de dados e recuperar dados do banco de dados MySQL da pilha.

```
<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 usa um objeto `DataSource` para se comunicar com o banco de dados MySQL. O Tomcat usa os dados no [web app context configuration file](create-custom-configure.md#create-custom-configure-context) para criar e inicializar um objeto `DataSource` e o associar a um nome lógico. Em seguida, ele registra o nome lógico usando um serviço de nomenclatura Java Naming and Directory Interface (JNDI). Para obter uma instância do objeto `DataSource` apropriado, você cria um objeto `InitialContext` e passa o nome lógico do recurso para o método `lookup` do objeto, que recupera o objeto apropriado. O nome lógico do exemplo SimpleJSP, `java:comp/env/jdbc/mydb`, tem os seguintes componentes:
+ O namespace raiz, `java`, separado do resto do nome por dois-pontos (:). 
+ Eventuais namespaces adicionais, separados por barras (/).

  O Tomcat adiciona automaticamente os recursos ao namespace `comp/env`.
+ O nome do recurso, definido no arquivo de configuração do contexto da aplicação da web e separado dos namespaces por uma barra.

  O nome do recurso deste exemplo é `jdbc/mydb`. 

Para estabelecer uma conexão com o banco de dados, SimpleJSP faz o seguinte:

1. Chama o método `DataSource` do objeto `getConnection`, que retorna um objeto `Connection`.

1. Chama o método `Connection` do objeto `createStatement` para criar um objeto `Statement`, que você usa para se comunicar com o banco de dados.

1. Comunica-se com o banco de dados chamando o método `Statement` apropriado.

   SimpleJSP chama `executeQuery` para executar uma consulta SHOW DATABASES, que lista os bancos de dados do servidor.

O método `executeQuery` retorna um objeto `ResultSet`, que contém os resultados da consulta. SimpleJSP obtém os nomes do banco de dados do objeto `ResultSet` retornado e os concatena para criar uma string de saída. Por fim, o exemplo fecha os objetos `ResultSet`, `Statement` e `Connection`. Para obter mais informações sobre JSP e JDBC, consulte [JavaServer Pages Technology](http://docs.oracle.com/javaee/5/tutorial/doc/bnagx.html) e [JDBC](http://docs.oracle.com/javase/tutorial/jdbc/basics/) Basics, respectivamente.

Para usar SimpleJSP com uma pilha, você deve colocá-lo em um repositório. Você pode usar qualquer um dos repositórios compatíveis, mas para usar SimpleJSP com a pilha de exemplo abordada na seção a seguir, você deve colocá-lo em um arquivo S3 público. Para obter informações sobre como usar os outros repositórios padrão, consulte [Repositórios de livro de receitas](workingcookbook-installingcustom-repo.md).

**Para colocar SimpleJSP em um repositório de arquivo S3**

1. Copie o código de exemplo para um arquivo chamado `simplejsp.jsp` e coloque o arquivo em um diretório chamado `simplejsp`.

1. Crie um arquivo `.zip` do diretório `simplejsp`.

1. Crie um bucket do Amazon S3 público, faça upload de `simplejsp.zip` no bucket e torne o arquivo público.

   Para obter uma descrição de como realizar esta tarefa, consulte [Começar a usar o Amazon Simple Storage Service](https://docs.aws.amazon.com/AmazonS3/latest/gsg/GetStartedWithS3.html).

## Criar um stack
<a name="create-custom-stack-stack"></a>

Para executar SimpleJSP você precisa de uma pilha com as camadas a seguir.
+ A camada do MySQL, que dá suporte ao servidor MySQL back-end.
+ Uma camada personalizada que usa o livro de receitas do Tomcat para dar suporte a instâncias do servidor Tomcat.

**Para criar a pilha**

1. No painel de OpsWorks pilhas, clique em **Adicionar pilha para criar uma nova pilha** e clique em **Avançado >>** para exibir todas as opções. Configure a pilha da maneira a seguir.
   + **Nome** — Um nome de pilha definido pelo usuário; este exemplo usa. TomStack
   + **Usar livros de receitas do Chef personalizados**: defina o botão seletor como **Sim** para exibir opções adicionais.
   + **Tipo de repositório**: Git.
   + **URL do repositório**: `git://github.com/amazonwebservices/opsworks-example-cookbooks.git`.
   + **JSON do Chef personalizado**: adicione o seguinte JSON:

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

   Para as opções restantes, você pode aceitar os valores padrão.

   O JSON personalizado faz o seguinte:
   + Substitui o atributo `['base_version']` do livro de receitas do Tomcat para definir o Tomcat versão como 7; o valor padrão é 6.
   + Substitui o atributo `['java_opts']` do livro de receitas do Tomcat para especificar que a instância é descentralizada e definir o tamanho máximo do heap do JVM como 256 MB; o valor padrão não define opções para instâncias que executem o Amazon Linux.
   + Especifica o valor do atributo `['datasources]`, que atribui um nome de recurso JDBC (jdbc/mydb) ao nome de contexto da aplicação da web (ROOT), conforme abordado em [tomcat::context](create-custom-configure.md#create-custom-configure-context).

     Este último atributo não tem valor padrão. Você deve defini-lo com JSON personalizado.  
![\[Configuration Management interface showing Chef version options and custom JSON input field.\]](http://docs.aws.amazon.com/pt_br/opsworks/latest/userguide/images/tom_add_stack.png)

1. Clique em **Add a layer**. Em **Layer type**, selecione **MySQL**. Em seguida, clique em **Add Layer**.

1. No painel de navegação, clique em **Instances** e em **Add an instance**. Clique em **Add Instance** para aceitar os padrões. Na linha da instância, clique em **start**.

1. Retorne à página **Layers** e clique em **\$1 Layer** para adicionar uma camada. Para **Layer type (Tipo de camada)**, clique em **Custom (Personalizado)**. O exemplo usa **TomCustom** e **tomcustom** como o nome da camada e o nome abreviado, respectivamente.  
![\[Add Layer form with Custom layer type, Name, and Short name fields for creating a customized layer.\]](http://docs.aws.amazon.com/pt_br/opsworks/latest/userguide/images/tom_add_custom_layer.png)

1. Na página **Layers**, para a camada personalizada, clique em **Recipes** e, em seguida, em **Edit**. Em **Custom Chef Recipes**, atribua as receitas do livro do Tomcat aos eventos do ciclo de vida da camada, da seguinte forma:
   + Para **Setup (Instalar)**, digite **tomcat::setup** e clique em **\$1**.
   + Para **Configure (Configurar)**, digite **tomcat::configure** e clique em **\$1**.
   + Para **Deploy (Implantar)**, digite **tomcat::deploy** e clique em **\$1**. Em seguida, clique em **Save**.

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

1. No painel de navegação, clique em **Apps** e em **Add an app**. Especifique as opções a seguir e clique em **Add App**:
   + **Nome** — O nome do aplicativo; o exemplo usa SimpleJSP e o nome curto gerado pelo OpsWorks Stacks será simplejsp.
   + **Tipo de aplicativo**: defina essa opção como **Outro**.

     OpsWorks O Stacks implanta automaticamente os tipos de aplicativos padrão nas instâncias do servidor associadas. Caso você defina **App type (Tipo de aplicativo)** como Other (Outro), o OpsWorks Stacks simplesmente executará as receitas de implantação e permitirá que elas lidem com a implantação.
   + **Raiz do documento**: defina essa opção como **ROOT**.

     O valor **Document root** especifica o nome do contexto.
   + **Tipo de repositório**: defina essa opção como **Arquivamento do S3**.
   + **URL do repositório**: defina como o URL do Amazon S3 do aplicativo que você criou anteriormente.

   Use as configurações padrão para as outras opções.  
![\[Application settings form with fields for name, app type, document root, and source details.\]](http://docs.aws.amazon.com/pt_br/opsworks/latest/userguide/images/tom_app.png)

1. Use a página **Instâncias** para adicionar uma instância à TomCustom camada e iniciá-la. OpsWorks O Stacks executa automaticamente as receitas de implantação em uma nova instância após a conclusão das receitas de configuração. Portanto, iniciar a instância também implanta o SimpleJSP.

1. Quando a TomCustom instância estiver on-line, clique no nome da instância na página **Instâncias** para ver seus detalhes. Copie o endereço IP público. Em seguida, construa uma URL da seguinte forma: http://*publicIP**appname.jsp*/tc/. Para o exemplo, esse URL será semelhante a **http://50.218.191.172/tc/simplejsp.jsp**.
**nota**  
O URL do Apache que encaminha solicitações para o Tomcat é definido como o atributo `['tomcat']['apache_tomcat_bind_path']` padrão, `/tc/`. A raiz do documento SimpleJSP é definida como `ROOT`, que é um valor especial resolvido como `/`. Por isso, o URL é ".../tc/simplejsp.jsp".

1. Cole o URL da etapa anterior no navegador. Você deve ver o seguinte:

   ```
   Databases found:
   information_schema
   simplejsp
   test
   ```
**nota**  
Se sua pilha tiver uma instância do MySQL OpsWorks , o Stacks cria automaticamente um banco de dados para cada aplicativo, nomeado com o nome abreviado do aplicativo.