Usando o Chef, parte 1

chef_0-nano

Chef é uma ferramenta para criação e configuração automática de novos hosts através de um conjunto programável de tarefas — as receitas — que executam ações específicas como instalar um pacote, criar um arquivo etc.

As tais receitas são escritas em uma DSL (Domain Specific Language), ou seja, uma linguagem criada para um determinado propósito. No caso do Chef ele está “pegando emprestado” a estrutura e sintaxe do Ruby para a tarefa.

Ruby?

Ao contrário do muitos acreditam, um sysadmin não é  um “empurrador de mouse com direitos de administrador”. Algum conhecimento em programação é sempre bem vindo para ajudar nas tarefas.

Nem que seja para duvidar sobre o que o realce de sintaxe do seu editor predileto está mostrando — a tela do nano (acima) foi proposital, pois está errada — ou para entender o que certos trechos de código estão a dizer:

10.times do
   puts 'eu não sei programar, e agora?'
done
end

Eu recomendo o curso Try Ruby (em inglês) do Code School para ajudar a dar uma ideia da sintaxe e comportamento do Ruby e, querendo se aprofundar um pouco mais, o Ruby (em inglês e português) do Codecademy. Todos são gratuitos, o primeiro é curtinho, tem duração15 minutos, e o segundo tem previsão de 9 horas.

Instalação

Obviamente é a primeira coisa a fazer é instalar o próprio Chef mas antes de prosseguir três conceitos básicos (explicações bem simplificadas):

  • Chef Server — É parte da infraestrutura de automação com a hospedagem de receitas e, como o próprio nome sugere, um serviço;
  • Chef Client —  É o cliente, o agente que cuida de “aplicar” as receitas  e
  • Chef DK (development kit) — é um pacote que inclui a o cliente e mais algumas ferramentas.

Neste caso vou instalar o Chef Development Kit — pois a ideia é “experimentar” e criar algumas receitas e não apenas executar as já prontas.

chef-1_chefdk

No momento em que estou escrevendo a versão mais recente é a 0.7.0 e o sistema operacional utilizado é uma máquina virtual com Ubuntu Server 15.04 (por mais que a última versão listada seja a 14.04 ele funciona).

O arquivo tem cerca de 136MiB e o download demorará um pouco. Quando terminado é hora de instalar:

$ sudo dpkg -i chefdk_0.7.0-1_amd64.deb
Selecting previously unselected package chefdk.
(Reading database ... 88666 files and directories currently installed.)
Preparing to unpack chefdk_0.7.0-1_amd64.deb ...
Unpacking chefdk (0.7.0-1) ...
Setting up chefdk (0.7.0-1) ...
Thank you for installing Chef Development Kit!

O pacote tem tudo aquilo que ele precisa mas se ocorrer algum erro na instalação e o dpkg informar a falta de algum pacote basta usar apt-get –fix-broken install para prosseguir.

Conceitos básicos

Alguns conceitos importantes para se entender o Chef:

  • Resource (recurso) — é algo que descreve um componente da infraestrutura (arquivo, modelo , pacote etc);
  • Recipe (receita) — é um agrupamento de recursos para prover a configuração de um servidor com determinadas característica e
  • Cookbook (livro de receitas) — É um agrupamento de receitas.

As referências gastronômicas não acabaram, ainda há mais algumas.

Antes de começar é bom criar um local para armazenar os arquivos do Chef, ele não faz distinção sobre o local onde ficarão os arquivos mas é sempre uma boa ideia deixar tudo em um único lugar, o pessoal do Chef sugere que seja criado um diretório chamado “chef-repo”, é apenas uma convenção mas eu irei segui-la também.

Criando uma receita

Agora é hora de criar um recurso (vou usar o mesmo exemplo do tutorial do Chef, ok?) con uma receita chamada “hello.rb” (lembram da história do Ruby?):

file 'motd' do
    content 'Olá mundo!'
end

Daí é só rodar o chef-apply para executar esta receita:

$ chef-apply hello.rb
Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * file[motd] action create
    - create new file motd
    - update content in file motd from none to b94d27
    --- motd 2015-10-04 11:26:31.195845194 -0300
    +++ ./.motd20151004-977-a8sz1b 2015-10-04 11:26:31.191845567 -0300
    @@ -1 +1,2 @@
    +Olá mundo!

No final você tem um arquivo chamado “motd” de conteúdo “Olá mundo!”. Não parece uma coisa tão legal assim já que você pode fazer o mesmo com o cat, echo, nano ou vi.

A diferença é que ele é um recurso, a existência e conteúdo dele estão registradas no Chef, assim se você modificar ou apagar este arquivo (recurso) ele o recriará com o mesmo conteúdo que você definiu inicialmente.

Se você rodar chef-apply novamente, obterá algo mais ou menos assim:

$ chef-apply hello.rb 
Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * file[motd] action create (up to date)

Ou seja, nada foi alterado mas se este arquivo for apagado ou tiver o conteúdo modificado, ele o restaurará à condição inicial:

$ echo "Este é meu arquivo e eu coloco nele o que quiser!" > motd 
$ chef-apply hello.rb Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * file[motd] action create
    - update content in file motd from 168979 to b94d27
    --- motd 2015-10-04 11:28:50.903793325 -0300
    +++ ./.motd20151004-1267-13r0wyk 2015-10-04 11:28:54.691489351 -0300
    @@ -1,2 +1,2 @@
    -Este é meu arquivo e eu coloco nele o que quiser!
    +Olá mundo!

Mas então isto ficará assim para sempre? Uma vez criado ele nunca poderá ser removido? Sendo um recurso do Chef ele pode ser removido pelo próprio programa.

Hora de criar o “goodbye.rb”:

file 'motd' do
    action :delete
end

Daí basta rodar o chef-apply para que este recurso seja corretamente removido:

$ chef-apply goodbye.rb 
Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * file[motd] action delete
    - delete file motd

Lembre que o recurso não é o arquivo “motd” e sim o trecho de código, o “hello.rb”, que o cria. A ação padrão para este recurso é o de criação, logo não existe a necessidade de se explicitamente  colocar um action :create nele.

Para terminar, as duas receitas acima trabalham com arquivos no diretório padrão onde a receita for executada, para indicar exatamente onde o arquivo deverá ser criado, basta indicar exatamente seu caminho:

file '/tmp/arquivos/arquivo_temporario.txt' do
    ...
end

E se for necessário criar (como recurso) um diretório:

directory '/tmp/arquivos/'

O Chef faz as coisas na ordem em que estão dentro do arquivo,  portanto você tem deve criar o diretório antes de sair colocando arquivos dentro dele, certo? 🙂

Uma receita mais sofisticada

Claro que o Chef serve para fazer coisas bem mais complicadas do que simplesmente ficar criando arquivos e diretórios, que tal uma receita mais complicada? Que tal instalar automaticamente o Apache e ainda definir uma nova página inicial:

package 'apache2'

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

file '/var/www/html/index.html' do
   mode 0644
   content '<!DOCTYPE html>
<html lang="pt_BR">
<head>
<meta charset="utf-8">
<title>Apache2 via Chef</title>
</head>
<body>
<h1>Olá mundo!</h1>
</body>
</html>'
end

Uma explicação sobre cada parte da receita:

package

O comando package, como o próprio nome indica, tem relação com o gerenciamento de pacotes do sistema operacional — aqui o Chef torna o sistema de empacotamento transparente para a receita, isto é, rodando em um CentOS ele usará o yum/rpm, em Debian o apt/dpkg e por aí vai dando suporte ao pors tree  dos BSD, brew do MacOS X e até mesmo o gems do Ruby.

Por ora é bom apenas ter ideia de que ele instalará o Apache 2 utilizando o sistema de pacotes padrão do sistema operacional e que na verdade a sintaxe deveria ser:

package "apache2" do
    action :install
end

Mas não é necessidade pois, assim como a ação padrão para um arquivo é a criação dele (“action :create”) a de um pacote é a instalação.

service

Ao ser instalado em package o Apache 2 passa a ser um recurso controlado pelo Chef, mais precisamente um serviço e o comando service a forma de controlá-lo. O primeiro parâmetro, o “supports”, serve para informar ao Chef que este pacote suporta a verificação do seu estado de execução.

Enquanto que as duas ações abaixo, passadas conjuntamente através de um array, ativa o serviço no sistema (“:enable”) e, claro, o põe em execução (“:start”).

file

E por último um sujeito já conhecido, o file, cuja função é criar um “index.html” específico, a propriedade “content” já foi explicada e diz respeito ao conteúdo do arquivo que será criado; a novidade é a propriedade “mode” que especificará as permissões do arquivo, no caso 0644.

Depois de tudo (razoavelmente) explicado é só aplicar a receita e como ela instalará um novo programa eu precisarei rodá-la com ajuda do sudo:

$ sudo chef-apply apache2.rb
Recipe: (chef-apply cookbook)::(chef-apply recipe)
  * apt_package[apache2] action install
    - install version 2.4.10-9ubuntu1.1 of package apache2
  * service[apache2] action enable
    - enable service service[apache2]
  * service[apache2] action start (up to date)
  * file[/var/www/html/index.html] action create
    - update content in file /var/www/html/index.html from ac5fd7 to
264e6b
    --- /var/www/html/index.html 2015-10-05 19:00:09.550696495 -0300
    +++ /var/www/html/.index.html20151005-14539-158se24 2015-10-05
        19:00:18.053444538 -0300
    @@ -1,376 +1,11 @@
    ...

A saída tem bastante coisa, e eu trunquei, por conta da alteração da página inicial do Apache mas o resultado final é este aqui:

chef_2-apache2

Saudades do Netscape Navigator onde o fundo padrão das  páginas era cinza 🙂

Finalizando (por enquanto)

E por enquanto é só e ao mesmo tempo já tem bastante informação aqui. Na próxima parte será a vez dos cookbooks — os livros de receitas — e, claro, como usá-las para automatizar a configurações de um ou vários hosts (e não seu próprio).

14 comentários sobre “Usando o Chef, parte 1

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

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

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

  4. Pingback: Vagrant – parte 1 | giovannireisnunes

  5. Parabéns pelo seu tutorial. Só faltou o “Olá mundo!” dentro do apache.rb, ficando assim:

    Apache2 via Chef

    Olá mundo!

    Curtir

  6. Pingback: Dois Anos! | giovannireisnunes

  7. Pingback: Utilizando o Ansible – parte 1 | giovannireisnunes

Os comentários estão desativados.