

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

# Exemplo 4: Adição do controle de fluxo
<a name="cookbooks-101-basics-ruby"></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).

Algumas receitas são apenas uma série de recursos do Chef. Neste caso, quando você executa a receita, ela simplesmente executa cada um dos provedores de recursos em sequência. No entanto, costuma ser útil ter um caminho de execução mais sofisticado. Estes são dois cenários comuns:
+ Você deseja que uma receita execute o mesmo recurso várias vezes com configurações de atributo diferentes.
+ Você deseja usar configurações de atributo diferentes em sistemas operacionais distintos.

Você pode abordar cenários como esses incorporando estruturas de controle do Ruby à receita. Esta seção mostra como modificar a receita de [Exemplo 3: Criação de diretórios](cookbooks-101-basics-directories.md) para resolver ambos os cenários.

**Topics**
+ [

## Iteração
](#cookbooks-101-basics-ruby-iteration)
+ [

## Lógica condicional
](#cookbooks-101-basics-ruby-conditional)

## Iteração
<a name="cookbooks-101-basics-ruby-iteration"></a>

[Exemplo 3: Criação de diretórios](cookbooks-101-basics-directories.md) mostrou como usar um recurso `directory` para criar um diretório ou uma cadeia de diretórios. No entanto, suponhamos que você queira criar dois diretórios separados, `/srv/www/config` e `/srv/www/shared`. Você pode implementar um recurso de diretório separado para cada diretório, mas essa abordagem pode atrapalhar caso você queira criar muitos diretórios. A receita a seguir mostra uma maneira mais simples de realizar a tarefa. 

```
[ "/srv/www/config", "/srv/www/shared" ].each do |path|
  directory path do
    mode 0755
    owner 'root'
    group 'root'
    recursive true
    action :create
  end
end
```

Em vez de usar um recurso de diretório separado para cada subdiretório, a receita usa uma coleção de strings que contém os caminhos de subdiretório. O método do Ruby `each` executa o recurso uma vez para cada elemento de coleção, começando pelo primeiro. O valor do elemento é representado no recurso pela variável `path`, que, neste caso, representa o caminho do diretório. Você pode adaptar facilmente este exemplo para criar qualquer número de subdiretórios.

**Para executar a receita**

1. Permaneça no diretório `createdir`; você usará esse livro de receitas nos vários próximos exemplos. 

1. Caso você ainda não tenha feito isso, execute `kitchen destroy` de maneira a começar com uma instância limpa. 

1. Substitua o código em `default.rb` pelo exemplo e execute `kitchen converge`.

1. Faça logon na instância; você verá os diretórios recém-criados em `/srv`.

Você pode usar uma tabela de hash a fim de especificar dois valores para cada iteração. A receita a seguir cria `/srv/www/config` e `/srv/www/shared`, cada um com um modo diferente.

```
{ "/srv/www/config" => 0644, "/srv/www/shared" => 0755 }.each do |path, mode_value|
  directory path do
    mode mode_value
    owner 'root'
    group 'root'
    recursive true
    action :create
  end
end
```

**Para executar a receita**

1. Caso você ainda não tenha feito isso, execute `kitchen destroy` de maneira a começar com uma instância limpa. 

1. Substitua o código em `default.rb` pelo exemplo e execute `kitchen converge`.

1. Faça logon na instância; você verá os diretórios recém-criados em `/srv` com os modos especificados.

**nota**  
OpsWorks As receitas de pilhas geralmente usam essa abordagem para extrair valores do [JSON de configuração e implantação da pilha](workingcookbook-json.md), que é basicamente uma grande tabela de hash, e inseri-los em um recurso. Para ver um exemplo, consulte [Receitas de implantação](create-custom-deploy.md).

## Lógica condicional
<a name="cookbooks-101-basics-ruby-conditional"></a>

Você também pode usar a lógica condicional do Ruby para criar várias ramificações de execução. A receita a seguir usa a lógica `if-elsif-else` para estender o exemplo anterior, de maneira que ela crie um subdiretório chamado `/srv/www/shared`, mas apenas em sistemas Debian e Ubuntu. Para todos os outros sistemas, ela registra uma mensagem de erro exibida na saída do Test Kitchen.

```
if platform?("debian", "ubuntu")
  directory "/srv/www/shared" do
    mode 0755
    owner 'root'
    group 'root'
    recursive true
    action :create
  end
else
  log "Unsupported system"
end
```

**Para executar a receita de exemplo**

1. Caso a instância ainda esteja em execução, execute `kitchen destroy` para desligá-la.

1. Substitua o código em `default.rb` pelo código de exemplo.

1. Edite `.kitchen.yml` para adicionar um sistema CentOS 6.4 à lista de plataformas. A seção `platforms` do arquivo deve ser semelhante.

   ```
   ...
   platforms:
     - name: ubuntu-12.04
     - name: centos-6.4
   ...
   ```

1. Execute `kitchen converge`, que irá criar uma instância e executar as receitas de cada plataforma em `.kitchen.yml` na sequência. 
**nota**  
Caso você queira apenas convergir uma instância, adicione o nome da instância como um parâmetro. Por exemplo, para convergir a receita apenas na plataforma Ubuntu, execute `kitchen converge default-ubuntu-1204`. Caso você esqueça os nomes da plataforma, basta executar `kitchen list`.

Você deve ver a mensagem de log na parte CentOS da saída do Test Kitchen, que será semelhante ao seguinte:

```
...
Converging 1 resources
Recipe: createdir::default
* log[Unsupported system] action write[2014-06-23T19:10:30+00:00] INFO: Processing log[Unsupported system] action write (createdir::default line 12)
[2014-06-23T19:10:30+00:00] INFO: Unsupported system
       
[2014-06-23T19:10:30+00:00] INFO: Chef Run complete in 0.004972162 seconds
```

Você já pode fazer logon nas instâncias e verifique se os diretórios foram criados ou não. No entanto, não basta executar `kitchen login` agora. Você deve especificar qual instância anexando o nome da plataforma; por exemplo, `kitchen login default-ubuntu-1204`. 

**nota**  
Caso um comando do Test Kitchen utilize o nome de uma instância, você não precisa digitar o nome completo. O Test Kitchen trata o nome de uma instância como uma expressão regular do Ruby. Assim, você precisa apenas de caracteres suficientes para apresentar uma correspondência exclusiva. Por exemplo, você pode convergir apenas a instância do Ubuntu executando `kitchen converge ub` ou fazer logon na instância do CentOS executando `kitchen login 64`.

A pergunta que você provavelmente tem a esta altura é como a receita sabe em qual plataforma está sendo executada. O Chef executa uma ferramenta chamada [Ohai](https://docs.chef.io/ohai.html) em todas as execuções que coletam dados do sistema, inclusive a plataforma, e representa como um conjunto de atributos em uma estrutura chamada de *objeto nó*. O método `platform?` do Chef compara os sistemas entre parênteses com o valor da plataforma Ohai e retorna verdadeiro caso haja correspondência de um deles.

Você pode consultar o valor de um atributo nó diretamente no código usando `node['attribute_name']`. O valor da plataforma, por exemplo, é representado por `node['platform']`. Você pode, por exemplo, ter escrito o exemplo anterior da maneira a seguir.

```
if node[:platform] == 'debian' or node[:platform] == 'ubuntu'
  directory "/srv/www/shared" do
    mode 0755
    owner 'root'
    group 'root'
    recursive true
    action :create
  end
else
  log "Unsupported system"
end
```

Um motivo comum para incluir lógica condicional em uma receita é acomodar o fato de que, às vezes, famílias do Linux diferentes usam nomes diferentes para pacotes, diretórios etc. Por exemplo, o nome do pacote do Apache é `httpd` em sistemas CentOS e `apache2` em sistemas Ubuntu.

Caso você só precise de uma string diferentes para sistemas distintos, o método [http://docs.chef.io/dsl_recipe.html#value-for-platform](http://docs.chef.io/dsl_recipe.html#value-for-platform) do Chef é uma solução mais simples do que `if-elsif-else`. A receita a seguir cria um diretório `/srv/www/shared` em sistemas CentOS, um diretório `/srv/www/data` em sistemas Ubuntu, e `/srv/www/config` em todos os outros.

```
data_dir = value_for_platform(
  "centos" => { "default" => "/srv/www/shared" },
  "ubuntu" => { "default" => "/srv/www/data" },
  "default" => "/srv/www/config"
)
directory data_dir do
  mode 0755
  owner 'root'
  group 'root'
  recursive true
  action :create
end
```

`value_for_platform` atribui o caminho apropriado a `data_dir` e o recurso `directory` usa esse valor para criar o diretório.

**Para executar a receita de exemplo**

1. Caso a instância ainda esteja em execução, execute `kitchen destroy` para desligá-la.

1. Substitua o código em `default.rb` pelo código de exemplo.

1. Execute `kitchen converge` e faça logon em cada instância para verificar se os diretórios apropriados estão presentes.