“`html
Guia técnico para estruturar playbooks com clareza e previsibilidade
Dominando a Arquitetura de Ansible
Se você quer evoluir suas automações sem virar refém de “copiar/colar”, a virada está em tratar
estrutura como parte do código: inventário, organização de diretórios, papéis, variáveis e idempotência.
1) Inventário e resolução de contexto: onde a ordem realmente importa
A primeira decisão arquitetural do Ansible é: como os hosts entram no sistema e como as variáveis
chegam neles. O que parece “detalhe” vira custo operacional quando o inventário cresce.
-
Use um formato previsível de inventário (ex.:
iniouYAML)
e defina grupos por intenção (ex.:web,db,edge),
não por acaso. -
Separe variáveis globais (aplicadas a tudo) de variáveis por grupo e
variáveis por host. Isso reduz o “efeito colateral” de valores acidentalmente sobrescritos. -
Entenda que a prioridade de variáveis é determinística. Se você deixa a resolução implícita,
o comportamento muda conforme arquivos e ordens — e isso mata a confiança no projeto.
Se estiver “funcionando”, mas ninguém sabe por quê, você tem um bug esperando acontecer.
2) Organização de diretórios: tratando playbooks como produto
Uma arquitetura saudável não depende de “memória”. Eu organizo o repositório para permitir que qualquer pessoa:
(1) encontre onde alterar, (2) saiba o que impacta, e (3) replique padrões sem inventar moda.
-
Mantenha playbooks no topo, com nome que explique o objetivo:
site.yml,deploy-web.yml,hardening.yml. -
Use roles para encapsular comportamento e permitir reuso.
Cada role deve ter uma responsabilidade clara (ex.: “nginx”, “firewall”, “base-os”). -
Centralize group_vars e host_vars no nível que faz sentido para o time.
Evite espalhar variáveis em múltiplos locais quando a regra é “variável de ambiente”. - Coloque templates, arquivos estáticos e handlers dentro da role que consome, não no “meio do caminho”.
ansible/
├─ ansible.cfg
├─ inventories/
│ ├─ prod/
│ │ ├─ hosts.ini
│ │ └─ group_vars/
│ │ ├─ all.yml
│ │ └─ web.yml
│ └─ staging/
│ ├─ hosts.ini
│ └─ group_vars/
│ ├─ all.yml
│ └─ web.yml
├─ playbooks/
│ ├─ site.yml
│ ├─ deploy-web.yml
│ └─ hardening.yml
├─ roles/
│ ├─ base-os/
│ │ ├─ tasks/main.yml
│ │ ├─ handlers/main.yml
│ │ └─ templates/
│ │ └─ ...
│ ├─ nginx/
│ │ ├─ tasks/main.yml
│ │ ├─ handlers/main.yml
│ │ └─ templates/
│ │ └─ nginx.conf.j2
│ └─ firewall/
│ ├─ tasks/main.yml
│ └─ defaults/main.yml
└─ group_vars/ (opcional, se você preferir um nível global)
3) Roles e playbooks: responsabilidade, composição e previsibilidade
A “arquitetura” do Ansible se concretiza na composição entre playbooks e roles.
O playbook descreve o que será feito (em que grupos/hosts), enquanto a role descreve como.
- No playbook, use roles de forma explícita e mínima. Evite “papel infinito” que faz tudo e dificulta testes.
-
Dentro da role, siga um fluxo claro em
tasks/main.yml:
pré-requisitos → configuração → serviços → validação. Isso aumenta legibilidade e facilita auditoria. -
Prefira handlers para ações reativas (ex.: reiniciar serviço apenas quando muda configuração).
Isso evita churn e reduz downtime desnecessário. -
Use
defaultsevarscom intenção:
defaults são “opcionais e seguros”; vars são “fixos do componente”.
Se tudo vira default, você perde governança.
você provavelmente está tentando encaixar responsabilidades demais no mesmo lugar.
4) Idempotência e execução: como garantir que o resultado é estável
A arquitetura não é só organização: é também como você garante que repetidas execuções mantêm o mesmo estado.
No Ansible, isso é idempotência na prática.
- Use módulos declarativos sempre que possível. Evite depender de comandos externos para alterações críticas.
-
Garanta que tarefas que alteram arquivos sejam feitas com módulos adequados (ex.: template/copy)
e ativem handlers apenas quando houver mudança real. -
Defina e respeite check mode e valide com
diffquando aplicável.
Isso reduz surpresas em pipelines. -
Estruture tarefas sensíveis com condições claras e variáveis bem definidas.
Quando a condição fica “mágica”, a manutenção vira adivinhação.
# roles/nginx/tasks/main.yml
- name: Instalar pacote do nginx
ansible.builtin.package:
name: nginx
state: present
- name: Gerar configuração do nginx
ansible.builtin.template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: "0644"
notify: Reiniciar nginx
- name: Garantir que o serviço está habilitado
ansible.builtin.service:
name: nginx
enabled: true
state: started
# roles/nginx/handlers/main.yml
- name: Reiniciar nginx
ansible.builtin.service:
name: nginx
state: restarted
Resultado esperado: a execução repetida só reinicia o serviço quando o template realmente muda, mantendo o comportamento previsível.
Próximo passo
Se você gostou do nível de clareza que uma boa arquitetura entrega, continua comigo:
leia outros posts para consolidar padrões de repositório, governança de variáveis e práticas de execução.
“`
Sou Apaixonado pela programação e estou trilhando o caminho de ter cada diz mais conhecimento e trazer toda minha experiência vinda do Design para a programação resultando em layouts incríveis e idéias inovadoras! Conecte-se Comigo!