04 - Ansible, Chef, Puppet (Configuração)
video: https://youtu.be/... no frontmatter da nota.Ansible, Chef, Puppet (Configuração)
Ansible, Chef e Puppet formam a família de ferramentas de gerenciamento de configuração do IaC: enquanto Terraform e CloudFormation criam recursos de nuvem, elas configuram o que roda dentro das máquinas, pacotes, arquivos, serviços, usuários e patches, mantendo o estado convergido ao longo do tempo. Ansible domina o mercado atual com execução sem agente por SSH e playbooks declarativos em YAML; Chef, com receitas escritas em Ruby, e Puppet, com modelo declarativo de agente e servidor, perderam espaço relativo, mas seguem em operações corporativas grandes, em especial onde há investimento histórico em suas plataformas. A distinção conceitual que organiza o módulo é provisioning versus configuration management: provisionar é fazer a máquina existir; configurar é torná-la útil e mantê-la correta. Em arquiteturas imutáveis, o papel dessas ferramentas migra para a construção de imagens e para o bootstrap; em frotas mutáveis de longa vida, elas continuam sendo o mecanismo de convergência contínua. Este arquivo cobre o modelo de cada ferramenta, o papel atual de cada uma no mercado e os critérios de comparação para decisão real.
Conceito: provisioning versus configuration management
Provisionamento cria a infraestrutura: rede, instância, disco, banco. Gerenciamento de configuração transforma a máquina recém-criada em servidor funcional: instala pacotes, escreve arquivos, habilita serviços, aplica hardening e mantém esse estado ao longo do tempo. A fronteira é limpa no desenho e frequente em discussão: Terraform não instala o runtime de aplicação no host, e Ansible não provisiona a VPC de forma idiomática. Operações maduras usam as duas camadas com fronteiras explícitas.
O problema que a camada de configuração resolve é a deriva. Uma frota mutável vive sob mudança contínua, patches, CVEs, ajustes de config, e sem convergência automática cada máquina vira um estado próprio. A ferramenta de configuração declara o estado desejado e reaplica em intervalo ou sob demanda: o servidor que deveria ter o agente de log instalado e não tem recebe o agente na próxima convergência, sem pessoa envolvida.
A distinção também muda com a imutabilidade. Em frota imutável, a configuração é congelada na golden image e o papel do gerenciamento de configuração se concentra na construção da imagem e na parametrização do boot. Em frota mutável, a convergência contínua é o mecanismo central de manutenção. A ferramenta certa depende, em parte, do modelo de frota que a operação adotou.
O problema que resolve
O alvo direto é a configuração manual via SSH, o fluxo em que o operador entra na máquina, edita arquivos e reinicia serviços, acumulando estados irreproduzíveis. Cada intervenção manual é uma diferença entre a máquina real e qualquer descrição que exista dela; cem máquinas sob intervenção manual são cem sistemas diferentes com o mesmo nome de serviço. Gerenciamento de configuração troca a intervenção por declaração e execução automática.
O segundo alvo é a escala da mudança. Atualizar a configuração de TLS em quinhentos servidores manualmente não é caro, é impossível de fazer de forma confiável; com convergência declarativa, é um commit reaplicado pela frota com rollout controlado. O terceiro alvo é a auditoria: com a configuração em código, o estado de qualquer máquina tem origem versionada, e o diff da última convergência responde o que mudou.
Há também o efeito de padronização organizacional. Módulos, roles e receitas compartilhados codificam padrões de segurança e operação: hardening de imagem, configuração de syslog, limites de kernel. O padrão deixa de ser documento para ser código aplicado, e a não conformidade vira problema detectável, não vira descoberta de auditoria seis meses depois.
Ansible: sem agente, SSH e playbooks idempotentes
Ansible executa de fora: um nó de controle conecta nas máquinas alvo por SSH e aplica módulos, sem agente instalado e sem serviço residente. O modelo simplifica adoção radicalmente, qualquer máquina alcançável por SSH é alvo imediato, e explica boa parte da ascensão da ferramenta; o custo é a exigência de conectividade e credenciais em massa, que em ambientes restritos vira projeto de rede e de chaves.
O código vive em playbooks YAML, com tasks que chamam modules idempotentes: package, service, template, copy, command. Inventários definem os grupos de alvo, roles organizam reuso, e variáveis e facts parametrizam a execução por ambiente. A idempotência é responsabilidade do autor, os módulos nativos cuidam disso por padrão, mas o módulo shell exige guarda, e é aí que playbooks mal escritos perdem a propriedade.
O modo ad-hoc é o segundo uso dominante: executar um comando em milhares de hosts de uma vez, com paralelismo controlado, é a rotina de operação que Ansible melhorou de forma mais visível. Reiniciar um serviço em frota, coletar versões, drenar nós, tudo isso vira uma linha de ansible com inventário e flag de paralelismo. Em plataforma de produção, o modo usual é push por CI, com credenciais efêmeras e inventário dinâmico gerado do próprio IaC.
# Playbook Ansible: hardening básico idempotente
- name: Preparar nós de aplicação
hosts: app_servers
become: true
tasks:
- name: Garantir pacotes base instalados
ansible.builtin.package:
name: "{{ item }}"
state: present # idempotente: só instala se faltar
loop:
- chrony
- logrotate
- name: Garantir serviço de tempo ativo
ansible.builtin.service:
name: chronyd
state: started
enabled: true # convergência, não ação pontual
- name: Aplicar limite de arquivos abertos no kernel
ansible.posix.sysctl:
name: fs.file-max
value: "262144"
sysctl_set: true
reload: true
- name: Distribuir configuração do agente de log
ansible.builtin.template:
src: agente-log.conf.j2 # template Jinja2 com variáveis
dest: /etc/agente-log/agente-log.conf
mode: "0644"
notify: reiniciar agente # handler roda só quando muda
Chef: receitas em Ruby e convergência
Chef organiza a configuração em cookbooks e receitas escritas em Ruby, uma DSL sobre uma linguagem de programação real, com resources declarativos, package, service, template, e o poder completo de Ruby quando necessário. A execução é por agente: o chef-client roda no host, em intervalo, busca o estado desejado no servidor Chef, converge o que divergiu e reporta o resultado. O modelo é de convergência contínua por agente, com pull periódico.
A força de Chef é a expressividade: lógica complexa, bibliotecas de helpers, testes em Test Kitchen com instâncias reais, e uma cultura de engenharia forte em torno do pipeline de infraestrutura. O custo é o mesmo poder: receitas mal escritas viram código imperativo difícil de auditar, e a curva de aprendizado é mais alta que Ansible, pois exige conforto com Ruby e com o modelo de execução distribuído.
A plataforma Chef exige infraestrutura própria, servidor de cookbooks, bancos de dados de nós, chaves de cliente, e esse custo operacional é parte do declínio relativo da ferramenta: o valor continuou bom, mas o custo total ficou difícil de justificar frente a modelos sem servidor central e sem agente.
# Receita Chef: convergência declarativa escrita em Ruby
package 'chrony' do
action :install # estado desejado, não comando
end
service 'chronyd' do
action [:enable, :start]
supports restart: true
end
template '/etc/chrony.conf' do
source 'chrony.conf.erb'
notifies :restart, 'service[chronyd]', :delayed # reinicia se mudou
end
Puppet: modelo declarativo com agente
Puppet é o modelo declarativo mais puro da tríade: o manifest descreve recursos e relações, package, service, file, com dependências e notificações explícitas, e o agente converge o host para esse estado periodicamente contra o Puppet Server. A linguagem de manifests é declarativa por desenho, com classes, módulos e Hiera para dados por ambiente, e o catálogo compilado para cada nó é o plano de convergência.
A força de Puppet é a governança em escala: catálogo por nó, relatórios de convergência, classificação de nós por regra e camada de dados separada do código com Hiera. É a ferramenta com melhor suporte nativo a auditoria contínua, pois cada run compara realidade com catálogo e reporta drift. O custo é similar ao de Chef: agente residente, servidor central e linguagem própria dominam a curva de adoção.
O desenho Puppet rende melhor quando o modelo é frota de longa vida com baseline forte: servidores corporativos, bancos legados, cargas que não são contêiner. Em plataformas de contêineres e VMs efêmeras, o benefício da convergência periódica diminui, pois as instâncias morrem antes de derivar, e o peso da infraestrutura Puppet deixa de compensar.
# Manifesto Puppet: classe declarativa com dependências explícitas
class base::tempo {
package { 'chrony':
ensure => installed, # estado desejado, não comando
}
service { 'chronyd':
ensure => running,
enable => true,
require => Package['chrony'],
}
file { '/etc/chrony.conf':
source => 'puppet:///modules/base/chrony.conf',
notify => Service['chronyd'], # reinicia quando a config muda
}
}
Papel atual de cada ferramenta no mercado
Ansible é hoje a ferramenta dominante de gerenciamento de configuração e a escolha padrão para automação operacional em geral, com fortaleza em três usos: configuração de hosts, orquestração de mudança em massa e automação de rede. A execução sem agente, o formato YAML e o ecossistema de collections do Galaxy consolidaram a adoção, inclusive em operações que já têm Terraform como camada de provisionamento.
Chef e Puppet mantêm presença sólida em corporações grandes, em especial financeiras e telecom, onde plataformas construídas ao longo de anos continuam valendo e onde a auditoria de convergência contínua é requisito regulatório. O movimento comum das duas é reduzir a superfície da plataforma, versões serverless das ferramentas, integração com nuvens, e coexistir com Ansible nas bordas. Novos projetos, na média do mercado, começam por Ansible ou por modelo imutável sem gerenciamento de configuração.
O recorte de decisão atual tem três perguntas. A frota é imutável em contêineres? Então gerenciamento de configuração é marginal, e o esforço vai para imagens. A frota é mutável de longa vida com baseline de compliance? Ansible cobre a maioria, e Chef ou Puppet valem quando a plataforma histórica existe ou a auditoria contínua por agente é exigência. Precisa de orquestração ad-hoc em massa? Ansible, quase sempre.
Comparação das três ferramentas
| Dimensão | Ansible | Chef | Puppet |
|---|---|---|---|
| Modelo de execução | Push, sem agente, por SSH | Pull, agente contra servidor Chef | Pull, agente contra Puppet Server |
| Linguagem | YAML, com Jinja2 | Ruby, DSL declarativa | DSL de manifests declarativa |
| Idempotência | Responsabilidade do autor, módulos ajudam | Resources declarativos | Resources declarativos |
| Convergência contínua | Sob demanda ou agente opcional | Nativa, runs periódicos | Nativa, runs periódicos |
| Curva de entrada | Baixa | Alta | Alta |
| Reuso | Roles e collections | Cookbooks e Test Kitchen | Módulos e Hiera |
| Infraestrutura extra | Nenhuma, só nó de controle | Servidor Chef | Puppet Server |
| Perfil típico | Automação geral e nuvem moderna | Corporativo com pipeline Ruby | Frota legada com compliance forte |
A leitura prática: Ansible pela simplicidade e cobertura, Chef quando o time vive Ruby e quer pipeline de infraestrutura com testes reais, Puppet quando o requisito central é catálogo, classificação e relatório de conformidade contínua em frota estável.
Erros comuns e boas práticas
- Escrever tasks com shell sem guarda de idempotência; use módulos nativos e, quando o shell for inevitável, proteja com checagem de estado.
- Misturar provisioning e configuração em uma única camada; Terraform cria, Ansible configura, e a fronteira precisa estar escrita em algum lugar que o time leia.
- Rodar playbooks com credenciais de longo prazo de máquinas de trabalho; use CI com role efêmera e inventário dinâmico vindo do IaC.
- Ignorar handlers e notificações; serviço que não reinicia quando a configuração muda é convergência pela metade.
- Manter segredos em variáveis de texto claro no repositório; use Ansible Vault ou gerenciador externo, e rotacione o que já vazou em histórico de Git.
- Aplicar convergência na frota inteira de uma vez; rollouts por lote com pausa de verificação são o mínimo de segurança operacional.
- Deixar a execução sem registro; log de run, diff aplicado e resultado por host são a trilha de auditoria que justifica a ferramenta.
- Copiar roles entre repositórios em vez de versioná-las; role é código e precisa de versão, changelog e dono, como qualquer biblioteca.