Boas Práticas no Desenvolvimento de Playbooks do Ansible

13/02/2025

Agora que entendemos o básico sobre o Ansible e como ele pode simplificar a automação de tarefas de TI, o próximo passo é aprender a criar playbooks de maneira eficiente e organizada. Playbooks bem estruturados não só facilitam a manutenção e a compreensão do código, mas também garantem que as automações sejam executadas de forma consistente e confiável. Mesmo em projetos de grande escala, seguir boas práticas na criação de playbooks pode fazer a diferença entre uma automação bem sucedida e um caos total.

Neste post, vamos explorar algumas dicas e boas práticas que irão te ajudar a escrever playbooks de alta qualidade. Essas práticas envolvem desde a estruturação do código até o uso eficiente de variáveis e templates, passando pela modularização com roles e a documentação adequada.

Estrutura Recomendada para Playbooks

Organizar seus playbooks de maneira consistente é super importante para facilitar tanto a leitura quanto a manutenção. Uma estrutura bem planejada mantém o código limpo e fácil de entender, evitando confusões e erros. Isso significa usar nomes claros para tudo, centralizar as variáveis e adicionar comentários que expliquem partes mais complicadas do código. Além disso, a modularização com roles divide o playbook em partes menores e mais gerenciáveis, cada uma com uma função específica. Isso facilita atualizações e manutenções. Roles também permitem a reutilização do código, garantindo consistência e economizando tempo, amos nos aprofundar neste assunto a seguir..

Seguindo essas práticas, você garante que seus playbooks sejam não só funcionais, mas também fáceis de entender e modificar por qualquer pessoa da equipe, assegurando uma automação eficiente e sustentável.. Abaixo conseguimos visualizar um exemplo de estrutura recomendada:

---
- name: Configurar servidor web
  hosts: webservers
  become: yes
  vars:
    http_port: 80
  tasks:
    - name: Instalar Apache
      apt:
        name: apache2
        state: present
    - name: Configurar Apache para iniciar na inicialização
      service:
        name: apache2
        enabled: yes
        state: started

Neste exemplo abordamos:

  • Name: Use um nome claro e intuitivo para cada playbook e tarefa
  • Hosts e become: Defina os hosts onde as tasks serão executadas e use become: yes se precisar de privilégios de superusuário (ou root para os mais íntimos do SO do Pinguim).
  • Variáveis: Declare variáveis (vars) no início para facilitar a reutilização e modificação.

——————————————————————————————————————————————————————————————————————————————

Modularização de Playbooks com Roles

Roles oferecem uma forma eficiente e organizada de dividir um playbook grande em partes menores e reutilizáveis, facilitando tanto a manutenção quanto a reutilização do código. Ao utilizar roles, você consegue estruturar suas tarefas de automação em componentes independentes e modulares, cada um desempenhando uma função específica. Podemos concordar que administrar playbooks com o uso de roles pode não ser simples, mas essa abordagem não só facilita a administração, como também melhora a clareza e a escalabilidade dos seus projetos. Eu sei, ficou um pouco redundantes rs.

Aqui estão alguns benefícios de usar roles em seus projetos:

  • Manutenção Facilitada: Roles permitem atualizar componentes específicos sem impactar todo o playbook, tornando a manutenção mais simples e ágil.
  • Reutilização de Código: Uma vez criada, uma role pode ser reutilizada em múltiplos playbooks e projetos, economizando tempo e esforço.
  • Organização e Clareza: Roles ajudam a manter os playbooks organizados, dividindo responsabilidades em partes lógicas e fáceis de gerenciar, o que facilita a colaboração em equipe.
  • Escalabilidade: A modularidade proporcionada pelas roles permite que seus projetos cresçam de maneira ordenada, garantindo que novas funcionalidades possam ser adicionadas sem complicações.
  • Isolamento de Funcionalidades: Cada role foca em uma única responsabilidade, tornando o código mais modular e fácil de entender, além de facilitar a identificação de problemas e a implementação de melhorias.
  • Documentação: Roles bem documentadas explicam claramente seu propósito, variáveis esperadas e dependências, o que é essencial para a manutenção e a colaboração.

Integrar roles em seus projetos é uma prática recomendada que contribuirá para a eficiência, organização e escalabilidade das suas automações.

Estrutura de Diretórios para Roles

Uma estrutura de diretórios bem organizada é essencial para trabalhar com roles de forma eficiente. Aqui está um exemplo de como estruturar suas roles corretamente:

site.yml
webservers.yml
roles/
   common/
      tasks/
         main.yml
      handlers/
         main.yml
      templates/
      files/
      vars/
         main.yml
      defaults/
         main.yml
      meta/
         main.yml
   webserver/
      tasks/
         main.yml
      handlers/
         main.yml
      templates/
         vhost.conf.j2
      files/
      vars/
         main.yml
      defaults/
         main.yml
      meta/
         main.yml
         

Os componentes de uma role no Ansible são como os tijolinhos que constroem suas automações. Cada diretório e arquivo tem uma função específica, garantindo que tudo fique organizado e fácil de entender.

No diretório tasks/, você coloca a lista de tarefas que a role vai executar, sempre em uma ordem lógica, com nomes claros e descritivos, e garantindo que possam ser rodadas várias vezes sem causar problemas (isso é o que chamamos de idempotência).

Em handlers/, você define ações que devem ser executadas quando notificadas por tarefas. Geralmente, são usadas para reiniciar serviços ou realizar ações específicas após uma mudança de configuração.

templates/ guarda arquivos de template Jinja2, que ajudam a criar configurações dinâmicas e adaptáveis com variáveis.

O diretório files/ é para arquivos estáticos que precisam ser copiados para os managed nodes.Ao contrário dos templates, esses arquivos não são processados pelo Jinja2 e são copiados diretamente

Em vars/ e defaults/, Use este diretório para definir variáveis que são necessárias para a role. Isso ajuda a manter as coisas organizadas e facilmente configuráveis.

Por fim, meta/ contém metadados sobre a role, como dependências de outras roles ou informações sobre a versão.

Seguindo essas recomendações, você mantém suas automações organizadas, fáceis de entender e prontas para evoluir conforme necessário.

Pontos de Atenção na criação de roles

Isolamento de Funcionalidades

Mantenha cada role focada em uma única responsabilidade. Isso torna o código mais modular e fácil de entender. Por exemplo, se você tem uma role para configurar um servidor web e outra para configurar um banco de dados, mantenha essas responsabilidades separadas em roles diferentes. Isso facilita a manutenção e a reutilização das roles em diferentes projetos.

Documentação

Documente cada role para explicar seu propósito e como deve ser usada. Inclua informações sobre as variáveis esperadas, os arquivos de configuração gerados e quaisquer dependências que a role possa ter. A documentação clara e completa é essencial para garantir que outros membros da equipe (ou você mesmo no futuro) possam entender e utilizar a role de maneira eficiente.

Reutilização

Crie roles que possam ser reutilizadas em diferentes projetos. Por exemplo, se você desenvolver uma role para configurar o Nginx como servidor web, essa role pode ser reutilizada em qualquer projeto que necessite do Nginx. Isso economiza tempo e mantém a consistência das configurações. Certifique-se de que as roles são suficientemente genéricas para serem aplicáveis em diversos contextos, sem a necessidade de grandes modificações.

Organização e Nomenclatura

Mantenha uma estrutura de diretórios organizada e use uma nomenclatura consistente para seus arquivos e diretórios. Isso facilita a navegação e a compreensão do código. Por exemplo, use nomes descritivos para suas roles, como webserver, database, load_balancer, etc. Além disso, organize as variáveis e templates em arquivos separados para manter o código limpo e organizado.e as variáveis e templates em arquivos separados para manter o código limpo e organizado.

——————————————————————————————————————————————————————————————————————————————

Uso Eficiente de Variáveis e Templates

As variáveis e templates são ferramentas poderosas para tornar seus playbooks mais dinâmicos e flexíveis. Usando variáveis, você pode ajustar a execução dos playbooks de acordo com o ambiente ou requisitos específicos, garantindo que as tasks se adaptem perfeitamente às suas necessidades. Templates são super úteis para criar arquivos de configuração dinâmicos que podem ser ajustados com base em variáveis. Isso significa que, em vez de criar várias versões de um arquivo de configuração, você pode usar um único template Jinja2 e personalizá-lo conforme necessário. Isso torna seus playbooks mais enxutos, eficientes e prontos para se adaptar a qualquer mudança. Dicas importantes:

  • Hierarquia de Variáveis: Compreenda a hierarquia de precedência das variáveis no Ansible para evitar conflitos e comportamentos inesperados.
  • Consistência: Use nomes consistentes para variáveis em todo o playbook. Isso facilita a leitura e a manutenção do código.
  • Templates: Utilize templates para arquivos de configuração complexos, tornando-os mais fáceis de atualizar e manter. Templates permitem que um único arquivo de configuração atenda a diferentes ambientes.
  • Segurança: Proteja variáveis sensíveis usando Ansible Vault. Isso garante que informações confidenciais, como senhas e chaves, não fiquem expostas.
  • Variáveis de Grupo: Utilize variáveis de grupo no inventário para definir valores comuns a todos os hosts de um grupo.

——————————————————————————————————————————————————————————————————————————————

Tasks e Handlers

Tasks e handlers são os pilares dos playbooks do Ansible. Escrever tarefas claras e garantir que sejam idempotentes, além de usar handlers de maneira eficaz, é fundamental para uma automação bem sucedida. Aqui estão algumas dicas para isso:

  • Idempotência: Certifique-se de que as tarefas possam ser executadas várias vezes sem causar problemas, mantendo o sistema no estado desejado. Isso evita surpresas quando o playbook é executado novamente.
  • Handlers: Use handlers para ações que só precisam ser executadas quando algo realmente muda, como reiniciar um serviço após uma atualização. Assim, você evita reinicializações desnecessárias.
  • Fail Fast: Configure as tarefas para falharem rapidamente em caso de erro, para que problemas possam ser detectados e resolvidos rapidamente, sem afetar outras partes do playbook.
  • Desempenho: Otimize suas tarefas para que sejam executadas rapidamente, usando módulos apropriados e evitando loops desnecessários, garantindo que suas automações sejam eficientes.

——————————————————————————————————————————————————————————————————————————————

Testes e Validação

Antes de colocar suas automações em produção, é super importante testar e validar seus playbooks. Isso ajuda a garantir que tudo funcione conforme o esperado e evita surpresas desagradáveis. Testar em um ambiente que simule o de produção o mais próximo possível é uma boa prática. Use ferramentas como ansible-lint para checar se o código está de acordo com as boas práticas e padrões do Ansible.

Dicas:

  • Ambiente de Teste: Sempre teste seus playbooks em um ambiente de teste que simule o ambiente de produção o mais próximo possível.
  • Linting: Utilize ferramentas como ansible-lint para verificar a conformidade do código com as boas práticas e padrões do Ansible.
  • Testes Automatizados: Implemente testes automatizados para validar seus playbooks e roles, utilizando ferramentas como Molecule.
  • Debugging: Use opções de debug e registro detalhado (-vvv ou -vvvv) para solucionar problemas em tarefas e handlers.

——————————————————————————————————————————————————————————————————————————————

Controle de Versão

Manter o controle de versão é essencial para garantir o histórico e a integridade dos seus playbooks. Aqui estão algumas dicas para te ajudar a fazer isso de maneira eficiente:

  • Versionamento: Use um sistema de controle de versão, como Git. Isso permite acompanhar todas as mudanças feitas nos seus playbooks e roles, colaborando com a equipe e revertendo para versões anteriores caso algo dê errado. Imagine isso como uma linha do tempo onde você pode ver exatamente o que foi feito e voltar no tempo, se necessário.
  • Commits: Sempre que fizer uma mudança, faça um commit com uma mensagem clara e descritiva. Isso ajuda a entender o que foi alterado e por quê, facilitando a vida de quem for revisar ou trabalhar no código depois. Por exemplo, ao invés de “mudança feita”, prefira algo como “adicionada configuração X para otimizar o Y”.
  • Branches: Use branches para desenvolver novas funcionalidades ou corrigir bugs. Isso mantém a branch principal (como main ou master) estável e facilita o gerenciamento de diferentes versões do projeto. Você pode criar uma branch para cada nova funcionalidade ou correção e, depois de testar e validar as mudanças, mesclá-las de volta na branch principal. Isso ajuda a manter o projeto organizado e sem conflitos de código.
  • Pull Requests: Sempre que for mesclar uma branch, utilize pull requests para revisar as mudanças. Isso permite que outros membros da equipe revisem o código, sugerindo melhorias e detectando possíveis problemas antes que as mudanças sejam integradas ao código principal.

——————————————————————————————————————————————————————————————————————————————

Documentação e Comentários

Manter uma boa documentação e adicionar comentários é fundamental para tornar seus playbooks e roles fáceis de entender e manter no futuro. Isso não só ajuda outros membros da equipe, mas também você mesmo quando precisar revisar o código depois de um tempo.:

  • Comentários: Adicione comentários úteis que expliquem partes complexas do playbook. Comentários podem esclarecer o motivo de certas decisões e facilitar o debugging. Por exemplo, em vez de apenas “instalando Apache”, você pode explicar por que está instalando o Apache e quais configurações específicas são importantes.
  • Documentação: Mantenha uma documentação atualizada para seus playbooks e roles. Inclua informações sobre variáveis, dependências e fluxos de trabalho. Isso pode ser feito através de README files ou documentações internas, detalhando o que cada parte do código faz, quais variáveis precisam ser configuradas e como a automação deve ser executada.

Seguindo essas práticas, você garante que seu código esteja sempre bem explicado e fácil de entender, independentemente de quem for trabalhar nele.

——————————————————————————————————————————————————————————————————————————————

Conclusão

Seguir boas práticas na criação de playbooks no Ansible é essencial para garantir automações eficientes, reutilizáveis e fáceis de manter. Organize seus playbooks de maneira consistente e utilize roles para modularizar suas tarefas. Variáveis e templates tornam seus playbooks mais dinâmicos, e garantir a idempotência das tarefas evita problemas. Teste e valide seus playbooks antes de aplicá-los em produção para evitar surpresas. Mantenha um controle de versão rigoroso e documente bem suas automações. Comentários úteis e documentação clara ajudam a entender e manter o código a longo prazo.

Seguindo essas práticas, você estará preparado para criar playbooks de alta qualidade que atendem às demandas de ambientes de TI complexos e em constante mudança.

Diego Henrique Carmo

Sou Engenheiro de Infraestrutura Sênior com mais de 10 anos trabalhando com tecnologia. Tenho bastante experiencia com Cloud, automação, IaC e Observabilidade. Sou apaixonado por aprendizado e acredito que o conhecimento é multiplicado quando compartilhado.