Usando o Chef, parte 2

chef-2_cookbook

Finalmente chega a segunda parte — estavam achando que eu tinha esquecido? — e ela conclui o conteúdo mais conceitual sobre Chef, na verdade até poderia ter ficado na primeira parte mas preferi segmentar para não deixá-la mais extensa que o habitual.

Livro de receitas (cookbook)

Apesar do que o nome possa transparecer, um cookbook não é bem um coletivo de receitas dentro de um mesmo diretório, ele seria mais uma espécie de “super receita” possuindo tanto estrutura como recursos específicos.

Ah sim, na primeira parte comentei que usar o diretório “~/chef-repo” seria uma sugestão, em parte está certo mas também também está errado! As receitas e os cookbooks até rodam em qualquer diretório mas algumas das ferramentas do Chef, por padrão, procurarão por coisas dentro dele 😐

Voltando ao diretório com os repositórios, o “~/chef-repo”, e criando nele um lugar específico para guardar os cookbooks:

$ mkdir -p ~/chef-repo/cookbooks
$ cd ~/chef-repo/cookbooks

E dentro deste diretório, o “nosso” primeiro cookbook:

$ chef generate cookbook instalar_apache2 --license gplv3 \
  --copyright "Giovanni Nunes" --email giovanni@localhost
Compiling Cookbooks...
Recipe: code_generator::cookbook
 * directory[/home/giovanni/chef-repo/instalar_apache2] action create
 - create new directory /home/giovanni/chef-repo/instalar_apache2]
...

Daí é aguardar enquanto a estrutura é criada…

Os parâmetros “- – license”, “- – copyright” e “- – email” são opcionais, eu os utilizei para que estes valores já fossem preenchidos automaticamente no arquivo “metadata.rb”.

A estrutura do cookbook é esta:

.
├── Berksfile
├── chefignore
├── metadata.rb
├── README.md
├── recipes
│   └── default.rb
├── spec
│   ├── spec_helper.rb
│   └── unit
│       └── recipes
│           └── default_spec.rb
└── test
    └── integration
        ├── default
        │   └── serverspec
        │       └── default_spec.rb
        └── helpers
            └── serverspec
                └── spec_helper.rb

Inclusive há um Berksfile, como nos projetos em Rails! 😀

Adaptando a receita

A primeira coisa é transplantar aquela receita que instalava o Apache para dentro do cookbook, isto é feito editando o arquivo “./recipes/default.rb”:

#
# Cookbook Name:: instalar_apache2
# Recipe:: default
#
# Copyright (C) 2015  Giovanni Nunes
# 
(...)

package 'apache2'

service 'apache2' do
    supports :status => true
    action [ :enable, :start ]
end

Nele copiei somente parte relacionada com a instalação do Apache (“package”) e seu registro no sistema como serviço (“service”). O arquivo “index.html” será colocado na receita de outra maneira.

Criando um modelo (template)

Ao invés de colocar um arquivo estático dentro da receita é possível usar um template. Além de melhorar em muito a legibilidade e manutenção — o arquivo não fica dentro da receita — permite incluir um certo grau de customização já que é possível executar código dentro dele.

Para criar um template, faça:

$ chef generate template instalar_apache2 index.html

O resultado da operação será um arquivo vazio — zero bytes — em “./templates/default” chamdo “index.html.erb”. Este sufixo é acrônimo de embedded ruby (ruby embutido), ou seja, ele permite a execução de código em Ruby dentro dele — funciona de um modo parecido com os arquivos de views em Rails.

Ou seja, ele é mais que um arquivo, é um (pequeno) programa. Então é possível sofisticá-lo para produzir resultados diferentes para cada host em que ele é aplicado (ou apenas fazer algo mais sofisticado que um “olá mundo”):

Os trechos em Ruby ficam dentro de “<%=%>” mas não sofistiquei muito, apenas usei parte do Ohai para saber um pouco mais sobre onde o código está sendo executado para a customização do  HTML.

Hora de acrescentá-lo em “./recipes/default.rb”:

template '/var/www/html/index.html' do
  source 'index.html.erb'
end

Pronto? Não, falta algo.

Inserindo um arquivo

Falando em customização, eu acrescentei também uma imagem (um arquivo estático) e como seria um pouco complicado embutir um PNG dentro da receita usarei ao invés do “file” o “cookbook_file”:

$ chef generate file instalar_apache2 rackserver.png

Este procedimento também criará um arquivo vazio, daí basta substituí-lo pelo que realmente será usado, neste caso a imagem aqui:

rackserver

É claro que o “file” continua disponível nas receitas e a opção de não usá-lo foi inteiramente minha.

E para fechar este cookbook, a inclusão da imagem:

cookbook_file '/var/www/html/rackserver.png' do
  source 'rackserver.png'
end

Agora está tudo pronto.

Executando o cookbook

É hora de testar, e isto é feito localmente, no host onde foi instalado o Chef DK. Aliás este é o motivo pelo qual ele é instalado, para criar um ambiente para se escrever, manter e testar receitas e cookbooks.

Como este passo envolve a instalação de pacotes (o Apache e suas dependências) e a escrita em “/var/www” usa-se o sudo:

$ cd ~/chef-repo
$ sudo chef-client --local-mode --runlist 'recipe[instalar_apache2]'
INFO: Started chef-zero at chefzero://localhost:8889 with repository
at /home/giovanni/chef-repo
  One version per cookbook
INFO: Forking chef instance to converge...
Starting Chef Client, version 12.4.1
INFO: *** Chef 12.4.1 ***
INFO: Chef-client pid: 12722
...
INFO: Report handlers complete
Chef Client finished, 4/5 resources updated in 79.257276704 seconds

O parâmetro “- – local-mode” serve para informar que o procedimento será local enquanto que “- – runlist” para relacionar quais cookbooks devem ser executados em sequência, como só existe um a lista se resume ao “instalar_apache2”.

O resultado final será algo mais assim:

chef-2_html

É possível comparar o produzido HTML com o template para ver onde os trechos em Ruby foram substituídos por valores específicos do host onde estou rodando o Chef DK. O endereço IP, que é o 192.168.0.9, o hostname, “chef”, e o sistema operacional, “ubuntu”.

Claro, como não tenho um servidor DNS rodando por aqui o FQDNfully qualified domain name — tem o mesmo valor que hostname.

E depois?

É claro que criar receitas e cookbooks para ficar rodando em um único host ainda está um pouco longe do objetivo final de configuração automática. Está faltando o principal componente da ferramenta, o Chef Server.

Dependendo da situação é possível utilizá-lo como um serviço que oferecido pela própria empresa que mantém o Chef, ou então configurando um para a sua própria rede… …que é o que farei 🙂

Então, até a terceira parte!

Anúncios

3 comentários sobre “Usando o Chef, parte 2

  1. Pingback: Usando o Chef, parte 2 - Peguei do

  2. Pingback: Usando o Chef, parte 3 | giovannireisnunes

  3. Pingback: Exemplo em Rails – parte 1 | giovannireisnunes

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s