Guia Completo de Playbooks no Ansible: Estrutura, Modularização e Práticas Avançadas
Introdução Geral
Os playbooks são o coração da automação no Ansible, permitindo definir e organizar tarefas para configurar e gerenciar sistemas de maneira eficiente e reproduzível. Neste guia completo, abordaremos desde os conceitos básicos de criação de playbooks até técnicas avançadas de segurança, modularização e boas práticas para ambientes complexos. Com um foco especial em segurança e organização, este tutorial é ideal tanto para iniciantes que desejam entender a estrutura de um playbook quanto para profissionais que buscam aprimorar suas habilidades com Ansible.
Tabela de Conteúdo
- Introdução ao Conceito de Playbooks no Ansible
- Estrutura e Sintaxe de um Playbook Ansible
- Execução de Tarefas com tasks e Modularização com handlers
- Uso de Variáveis em Playbooks
- Loops e Iterações em Tarefas
- Uso de Filtros para Manipulação de Variáveis
- Condicionais com when para Controle de Execução
- Uso de Blocos (block) e Tratamento de Erros com rescue
- Uso de Arquivos include e Modularização com import_tasks
- Estrutura e Uso de Roles em Playbooks
- Segurança em Playbooks
- Ferramentas de Debugging e Testes
- Execução de Playbooks e Parâmetros Comuns
- Boas Práticas para Organização e Manutenção de Playbooks
1. Introdução ao Conceito de Playbooks no Ansible
Objetivo
Apresentar o conceito de playbooks e destacar sua importância na automação de tarefas, diferenciando-os de comandos ad-hoc e detalhando suas vantagens na organização e automação de configurações complexas.
Conteúdo
O que São Playbooks no Ansible?
No Ansible, os playbooks são arquivos escritos em YAML que definem uma ou mais “plays” (conjuntos de instruções) para execução em hosts gerenciados. Em um playbook, cada play contém tarefas (tasks) que especificam ações para configurar sistemas, implantar aplicativos e gerenciar ambientes complexos.
Resumo:
- Formato YAML: Simples e legível, usado para definir a sequência de tarefas.
- Estrutura Modulada: Contém uma ou mais “plays”, onde cada play define um conjunto de tarefas a serem executadas em um ou mais hosts.
- Automação Completa: Permite combinar tarefas sequenciais e condicionais, oferecendo automação robusta.
Como os Playbooks Facilitam a Automação de Tarefas Complexas
A principal vantagem dos playbooks é a capacidade de definir workflows automatizados e consistentes. Diferente de comandos ad-hoc, que são executados uma única vez para tarefas pontuais, os playbooks documentam e organizam fluxos completos, permitindo repetir e rastrear cada passo.
Principais Benefícios:
- Automação Reprodutível: A execução de um playbook garante que todos os passos sejam realizados da mesma forma em cada execução.
- Controle de Fluxo e Condições: Permite o uso de condicionais (
when), loops (with_items,loop), variáveis, e módulos de controle de fluxo (comoblockerescue). - Documentação e Manutenção: O próprio playbook serve como uma documentação dos procedimentos, facilitando o compartilhamento e a manutenção das tarefas automatizadas.
Diferença entre Comandos Ad-Hoc e Playbooks
- Comandos Ad-Hoc: Executam uma única tarefa rápida e pontual diretamente na linha de comando.
- Playbooks: Estruturam múltiplas tarefas sequenciais e interdependentes. São reutilizáveis, documentam cada passo e incluem configurações como variáveis e roles.
Exemplo:
- Comando Ad-Hoc:
ansible all -m apt -a "name=nginx state=present" -b- Instala o pacote
nginxem todos os hosts de uma vez, mas não define uma sequência.
- Instala o pacote
- Playbook: Um playbook permite definir múltiplas tarefas — como instalação, configuração de arquivos e reinício do serviço — com passos organizados e interdependentes.
Vantagens de Usar Playbooks para Organização e Automação de Configurações
Com playbooks, é possível automatizar cenários complexos em que múltiplos servidores, variáveis e condições estão envolvidos. Isso traz uma série de vantagens para o gerenciamento de infraestrutura:
- Consistência e Confiabilidade: O playbook garante que cada tarefa será executada da mesma forma em cada execução, eliminando variações que ocorrem em execuções manuais.
- Escalabilidade: Com playbooks, a automação pode facilmente ser escalada para centenas de servidores com uma única execução.
- Flexibilidade e Modularidade: Playbooks permitem organizar tarefas em blocos lógicos (como
blockehandlers), com opções para tratamento de erros, reuso de tarefas, e integração com roles (papéis) que encapsulam configurações específicas de cada serviço.
Exemplo Simples de Playbook para Instalação de Pacotes
Abaixo está um exemplo básico de um playbook que instala o pacote
nginxe configura o serviço para iniciar automaticamente em servidores de um grupo de hosts chamadowebservers:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
--- - name: Configuração de Servidor Web com Nginx hosts: webservers become: yes tasks: - name: Instalar o pacote nginx apt: name: nginx state: present when: ansible_os_family == "Debian" - name: Iniciar e habilitar o serviço nginx service: name: nginx state: started enabled: yes
Explicação:
name: Fornece um título descritivo para o play e para cada tarefa.hosts: Define o grupo de hosts onde o play será executado (webservers).become: Permite a execução com privilégios elevados.tasks: Lista de tarefas a serem executadas, incluindo a instalação e ativação do serviçonginx.
Resumo
Playbooks são a ferramenta central do Ansible para automação de tarefas complexas, proporcionando uma estrutura organizada, flexível e robusta. Ao contrário dos comandos ad-hoc, os playbooks permitem controlar fluxos, definir dependências e incluir condições de execução, facilitando a automação de ambientes de TI modernos.
Na próxima seção, exploraremos a estrutura e sintaxe básica dos playbooks, detalhando a formatação YAML e os principais componentes para começar a criar playbooks funcionais no Ansible.
2. Estrutura e Sintaxe de um Playbook Ansible
Objetivo
Explicar a estrutura básica de um playbook no Ansible e apresentar suas principais diretivas, para que o leitor compreenda a organização e a formatação de um playbook simples.
Conteúdo
Estrutura Básica do Playbook em YAML
Playbooks no Ansible são escritos em YAML, um formato de dados simples e legível que usa indentação para organizar as informações. Alguns pontos importantes sobre a sintaxe YAML para playbooks incluem:
- Indentação: No YAML, a indentação define a estrutura e deve ser consistente (espaços, não tabulações).
- Listas e Pares Chave-Valor: Playbooks são compostos por listas (
- item) e pares chave-valor (chave: valor). - Organização em Níveis: Cada seção do playbook é organizada em níveis, como
hosts,tasks,vars, etc., com indentação para separar as subtarefas e opções.
Exemplo Básico de Estrutura YAML:
1 2 3 4 5 6 7 8
- name: Exemplo de playbook hosts: all become: yes tasks: - name: Instalar o Apache apt: name: apache2 state: present
Componentes Principais de um Playbook
Um playbook básico contém alguns componentes essenciais que definem o escopo e a execução das tarefas:
- hosts: Define em quais servidores as tarefas serão executadas (ex.:
all,webservers). - tasks: Uma lista de tarefas que serão executadas sequencialmente.
- vars: Variáveis definidas dentro do playbook para uso nas tarefas, tornando-o mais dinâmico.
- handlers: Tarefas especiais que só são acionadas se notificadas por outras tarefas (úteis para reiniciar serviços após alterações de configuração).
- hosts: Define em quais servidores as tarefas serão executadas (ex.:
Diretivas Principais de um Playbook
hosts: Especifica o(s) grupo(s) de hosts no qual o playbook será executado.1
hosts: webservers
become: Define se a execução deve ocorrer com privilégios elevados (yespara ativar sudo).1
become: yes
tasks: Lista de ações a serem executadas sequencialmente, com uma estrutura chave-valor. ```yaml tasks:- name: Instalar nginx apt: name: nginx state: latest ```
vars: Define variáveis específicas do playbook, permitindo reuso de valores e personalização.1 2 3
vars: web_package: nginx version: latest
handlers: Tarefas executadas em resposta a notificações de outras tarefas. ```yaml handlers:- name: Reiniciar o nginx service: name: nginx state: restarted ```
Exemplo de um Playbook Básico para Instalação de Pacotes
Vamos montar um exemplo de playbook que instala e configura o serviço
nginxem servidores de um grupo chamadowebservers. Esse exemplo inclui o uso de uma variável e um handler:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
--- - name: Instalação e Configuração do Nginx hosts: webservers become: yes vars: web_package: nginx tasks: - name: Instalar o pacote Nginx apt: name: "{{ web_package }}" state: present when: ansible_os_family == "Debian" notify: Reiniciar o Nginx - name: Configurar arquivo de boas-vindas copy: content: "Bem-vindo ao servidor Nginx!" dest: /var/www/html/index.html handlers: - name: Reiniciar o Nginx service: name: nginx state: restarted
Explicação:
- Play: Chama-se “Instalação e Configuração do Nginx” e aplica as tarefas no grupo
webservers. - Variável
web_package: Define o nome do pacote comonginx, permitindo que o playbook seja mais fácil de modificar se o pacote mudar. - Tarefa de Instalação: Usa o módulo
aptpara instalar o Nginx e só executa em sistemas Debian (when: ansible_os_family == "Debian"). - Tarefa de Configuração: Usa o módulo
copypara criar um arquivo de boas-vindas. - Handler: Reinicia o serviço
nginxse notificado, o que ocorre após a instalação do pacote.
- Play: Chama-se “Instalação e Configuração do Nginx” e aplica as tarefas no grupo
Resumo dos Componentes com uma Tabela de Referência
Componente Função Exemplo de Uso hostsDefine os hosts onde o play será executado. hosts: webserversbecomeDefine se as tarefas devem ser executadas com sudo. become: yestasksLista de tarefas que o play executará. tasks: - name: Instalar nginx ...varsDefine variáveis usadas no playbook. vars: web_package: nginxhandlersTarefas executadas sob demanda após uma notificação. notify: Reiniciar o Nginx
Resumo
A estrutura e sintaxe de um playbook Ansible são baseadas em YAML e incluem componentes essenciais como hosts, tasks, vars e handlers. Com esses elementos, é possível criar playbooks simples e organizados, que permitem a execução sequencial de tarefas em um ou mais hosts de forma automatizada.
Na próxima seção, abordaremos a execução de tarefas com tasks e a modularização com handlers, avançando na construção de playbooks mais robustos e organizados.
3. Execução de Tarefas com tasks e Modularização com handlers
Objetivo
Demonstrar como definir tarefas (tasks) sequenciais e modularizar a execução com handlers, garantindo que as tarefas sejam executadas de forma organizada e que ações específicas, como reiniciar serviços, só ocorram quando necessário.
Conteúdo
Configuração de
taskspara Execução de Tarefas SequenciaisEm um playbook Ansible, o componente
taskscontém a lista de ações que serão executadas em sequência. Cadataské uma ação que utiliza módulos do Ansible, comoapt,yum,service,copy, entre outros, para realizar operações de instalação, configuração e monitoramento. Cada tarefa recebe um nome descritivo e pode ser parametrizada com variáveis e condicionais.Exemplo de Tarefa Simples:
1 2 3 4 5 6 7 8 9
tasks: - name: Instalar o pacote nginx apt: name: nginx state: present - name: Copiar arquivo de configuração customizado copy: src: /local/path/nginx.conf dest: /etc/nginx/nginx.conf
name: Descrição da tarefa, facilitando a leitura do playbook e a depuração da execução.aptecopy: Módulos específicos que executam operações (instalação de pacote e cópia de arquivo).
Modularização com
handlerspara Ações Sob DemandaUm
handleré uma tarefa que só é executada quando notificada por outra tarefa. Isso é útil para tarefas como reiniciar serviços ou atualizar configurações, que não precisam ser executadas sempre, mas somente após uma mudança relevante.- Quando usar
handlers:handlerssão ideais para tarefas que devem ocorrer apenas quando uma alteração acontece, como reiniciar um serviço após modificar um arquivo de configuração. - Sintaxe de
notify: Dentro da tarefa que requer ohandler, utilizenotify: <nome_do_handler>para chamar o handler apenas se a tarefa provocar alguma mudança no sistema.
Exemplo de Uso de
handlerspara Reiniciar um Serviço após Configuração1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
tasks: - name: Instalar o nginx apt: name: nginx state: present notify: Reiniciar o nginx - name: Copiar configuração do nginx copy: src: /local/path/nginx.conf dest: /etc/nginx/nginx.conf notify: Reiniciar o nginx handlers: - name: Reiniciar o nginx service: name: nginx state: restarted
- Explicação:
- As tarefas
Instalar o nginxeCopiar configuração do nginxnotificam o handlerReiniciar o nginx. - O handler
Reiniciar o nginxsó será executado se alguma das tarefas acima provocar uma mudança (ex.: se o arquivo de configuração foi atualizado).
- As tarefas
- Quando usar
Usando Condicionais com
whenpara Executar Tarefas Sob CondiçãoCondicionais permitem que uma tarefa seja executada apenas se uma condição específica for atendida. Isso pode ser útil para evitar erros de execução em sistemas incompatíveis ou para adaptar o playbook para diferentes ambientes.
Exemplo de Uso de
whenpara Condicionar a Execução em Sistemas Debian1 2 3 4 5 6
tasks: - name: Instalar o nginx apenas em Debian apt: name: nginx state: present when: ansible_os_family == "Debian"
- Explicação:
when: ansible_os_family == "Debian": Condiciona a tarefa para ser executada apenas em hosts com sistema operacional da família Debian.
- Explicação:
Exemplo Prático de um Playbook com
tasksehandlersO exemplo a seguir mostra um playbook que instala o Nginx, copia uma configuração e reinicia o serviço Nginx apenas se a configuração for alterada:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
--- - name: Configuração do Servidor Web com Nginx hosts: webservers become: yes tasks: - name: Instalar o pacote Nginx apt: name: nginx state: present when: ansible_os_family == "Debian" notify: Reiniciar o Nginx - name: Copiar arquivo de configuração do Nginx copy: src: /local/path/nginx.conf dest: /etc/nginx/nginx.conf notify: Reiniciar o Nginx handlers: - name: Reiniciar o Nginx service: name: nginx state: restarted
Explicação do Exemplo:
- Tarefas: Instala o Nginx e copia o arquivo de configuração.
- Condição: A instalação ocorre apenas em sistemas da família Debian.
- Notificação e Handler: As tarefas de instalação e configuração notificam o handler
Reiniciar o Nginx, que só é executado se houver uma mudança.
Tabela de Referência: Principais Opções de
tasksehandlersParâmetro Descrição Exemplo nameNome descritivo para a tarefa ou handler name: Instalar nginxnotifyChama um handler caso haja mudança notify: Reiniciar o nginxwhenCondiciona a execução da tarefa when: ansible_os_family == "Debian"handlersDefine tarefas que respondem a notificações handlers: - name: Reiniciar o nginx ...
Resumo
O uso de tasks e handlers permite organizar as tarefas do playbook de forma sequencial e condicional, criando um fluxo de execução mais eficiente e modular. A notificação de handlers permite que ações sensíveis, como reiniciar serviços, ocorram apenas quando necessário, enquanto as condicionais controlam a execução com base em critérios específicos.
Na próxima seção, exploraremos como definir e utilizar variáveis em playbooks, o que facilita a personalização e reutilização de playbooks em diferentes ambientes e configurações.
4. Uso de Variáveis em Playbooks
Objetivo
Explicar como definir e utilizar variáveis em playbooks para torná-los dinâmicos e personalizáveis. Essa prática ajuda a adaptar o mesmo playbook a diferentes ambientes e configurações.
Conteúdo
Declaração de Variáveis no Playbook
No Ansible, as variáveis permitem que um playbook seja mais flexível e adaptável, removendo a necessidade de valores fixos e facilitando o reuso. As variáveis podem ser declaradas diretamente no playbook usando a diretiva
vars.Exemplo de Declaração Simples com
vars:1 2 3
vars: web_package: nginx web_port: 80
- Explicação:
web_package: Nome do pacote a ser instalado, permitindo a fácil substituição por outro servidor web se necessário.web_port: Porta a ser configurada, útil para definir diferentes portas em diferentes ambientes.
- Explicação:
Uso de Variáveis do Inventário e Arquivos Externos
Além de declarar variáveis no próprio playbook, você pode definir variáveis no inventário (
inventory) ou em arquivos externos (vars_files). Essa prática é útil para separar configurações e personalizar variáveis por host ou grupo.Exemplo de Variáveis no Inventário:
1 2 3
[webservers] server1 ansible_host=192.168.1.10 web_port=8080 server2 ansible_host=192.168.1.11 web_port=8081
- Explicação:
- Cada servidor tem uma configuração personalizada de
web_port, que pode ser acessada no playbook usando{{ web_port }}.
- Cada servidor tem uma configuração personalizada de
Exemplo de Uso de
vars_filespara Importar Variáveis de Arquivos Externos:1 2
vars_files: - vars/web_config.yml
O conteúdo de
web_config.ymlpode ser algo como:1 2
web_package: apache2 max_clients: 200
- Explicação:
Utilizando Variáveis no Playbook
Para usar uma variável em um playbook, utilize a sintaxe
{{ variavel }}, com o valor da variável sendo automaticamente substituído no momento da execução.Exemplo de Uso de Variáveis em Tarefas:
1 2 3 4 5 6 7 8 9 10
- name: Instalar o servidor web definido apt: name: "{{ web_package }}" state: present - name: Configurar a porta do servidor lineinfile: path: /etc/nginx/nginx.conf regexp: 'listen' line: "listen {{ web_port }};"
- Explicação:
{{ web_package }}: O Ansible substituiweb_packagepelo valor configurado (nginxouapache2).{{ web_port }}: Define a porta no arquivo de configuração com base no valor da variável.
- Explicação:
Ordem de Precedência das Variáveis
O Ansible aplica variáveis em uma ordem de precedência que determina qual valor será usado em caso de conflitos. A ordem das variáveis (da mais baixa para a mais alta prioridade) é:
- Variáveis padrão definidas em
roles. - Variáveis definidas em
group_varsouhost_vars. - Variáveis de inventário.
- Variáveis de linha de comando (
-e).
Exemplo de Sobrescrita de Variáveis:
1
ansible-playbook playbook.yml -e "web_port=8080"
- Explicação:
- A variável
web_portdefinida na linha de comando substitui qualquer valor anterior da mesma variável no playbook.
- A variável
- Variáveis padrão definidas em
Exemplo Prático: Configurando um Servidor Web com Variáveis Personalizáveis
O exemplo abaixo mostra um playbook que usa variáveis para definir o pacote do servidor web, a porta de escuta e o diretório raiz:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
--- - name: Configuração Personalizada do Servidor Web hosts: webservers become: yes vars: web_package: nginx web_port: 8080 web_root: /var/www/html tasks: - name: Instalar o servidor web apt: name: "{{ web_package }}" state: present when: ansible_os_family == "Debian" - name: Configurar a porta de escuta lineinfile: path: /etc/nginx/nginx.conf regexp: 'listen' line: "listen {{ web_port }};" notify: Reiniciar o serviço nginx - name: Definir o diretório raiz file: path: "{{ web_root }}" state: directory owner: www-data group: www-data mode: '0755' handlers: - name: Reiniciar o serviço nginx service: name: nginx state: restarted
- Explicação do Exemplo:
- As variáveis
web_package,web_porteweb_rootpermitem modificar facilmente o comportamento do playbook sem precisar editar as tarefas. - Cada variável é utilizada na tarefa correspondente, facilitando a personalização do servidor web.
- As variáveis
- Explicação do Exemplo:
Tabela de Referência para o Uso de Variáveis em Playbooks
Local Descrição Exemplo varsVariáveis definidas diretamente no playbook vars: web_package: nginxinventoryDefinidas por host ou grupo no inventário server1 ansible_host=192.168.1.10 ...vars_filesImporta variáveis de um arquivo externo vars_files: - vars/config.ymlLinha de comando Variáveis de alta prioridade -e "web_port=8080"
Resumo
O uso de variáveis permite que playbooks sejam dinâmicos e facilmente adaptáveis a diferentes configurações e ambientes. Declarar variáveis diretamente no playbook, no inventário ou em arquivos externos torna o gerenciamento de configurações mais flexível e organizado. A compreensão da precedência das variáveis também ajuda a evitar conflitos e definir corretamente os valores de execução.
Na próxima seção, vamos explorar o uso de loops e iterações, facilitando a execução de tarefas repetitivas e otimizando a configuração de múltiplos itens com uma única tarefa.
5. Loops e Iterações em Tarefas
Objetivo
Demonstrar como executar tarefas repetitivas usando loops no Ansible para otimizar a configuração de múltiplos itens com uma única tarefa.
Conteúdo
Introdução aos Loops no Ansible
Loops permitem que uma mesma tarefa seja executada repetidamente para uma lista de itens, o que é útil para configurações em lote, como instalação de pacotes, criação de múltiplos usuários ou configuração de arquivos em série. O Ansible oferece várias diretivas para loops, incluindo
loop,with_itemsewith_dict, cada uma apropriada para tipos de dados específicos.Uso de
looppara Listas SimplesA diretiva
loopé uma das maneiras mais flexíveis de iterar sobre listas. Ela permite repetir uma tarefa para cada item de uma lista, substituindo o item atual com a variável{{ item }}.Exemplo: Instalação de Múltiplos Pacotes Usando
loop1 2 3 4 5 6 7 8 9
tasks: - name: Instalar pacotes necessários apt: name: "{{ item }}" state: present loop: - nginx - git - curl
- Explicação:
loop: Itera sobre a lista de pacotes (nginx,git,curl), instalando cada um.{{ item }}: Referencia o item atual do loop, permitindo a execução repetida da tarefa para cada pacote.
- Explicação:
Usando
with_itemspara Iteração sobre ListasA diretiva
with_itemsé similar aoloope permite a execução da tarefa para cada item de uma lista. Embora olooptenha substituído muitos usos dowith_items, este último ainda é útil para versões anteriores do Ansible.Exemplo: Configurar Vários Arquivos Usando
with_items1 2 3 4 5 6 7 8 9
tasks: - name: Configurar múltiplos arquivos copy: src: "/configuracoes/{{ item }}.conf" dest: "/etc/{{ item }}.conf" with_items: - app1 - app2 - app3
- Explicação:
with_items: Itera sobre a lista (app1,app2,app3).srcedest: Copiam arquivos específicos com base no valor atual de{{ item }}.
- Explicação:
Uso de Loops com Dicionários (
with_dict)Em casos onde precisamos iterar sobre um conjunto de pares chave-valor, o Ansible oferece a diretiva
with_dict, que facilita o gerenciamento de configurações complexas.Exemplo: Configuração de Usuários e Senhas Usando
with_dict1 2 3 4 5 6 7 8 9 10
tasks: - name: Criar usuários com senhas user: name: "{{ item.key }}" password: "{{ item.value }}" state: present with_dict: users: alice: "{{ 'senha1' | password_hash('sha512') }}" bob: "{{ 'senha2' | password_hash('sha512') }}"
- Explicação:
with_dict: Itera sobre o dicionáriousers, ondealiceebobsão chaves (nomes de usuário) e os valores são suas senhas criptografadas.item.keyeitem.value: Referenciam o nome e a senha de cada usuário.
- Explicação:
Looping com Variáveis em Objetos Complexos
É possível usar loops com listas complexas, iterando sobre propriedades específicas dos objetos.
Exemplo: Configurar Vários Usuários com Permissões e Senhas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
vars: usuarios: - nome: alice senha: "{{ 'senhaAlice' | password_hash('sha512') }}" shell: /bin/bash - nome: bob senha: "{{ 'senhaBob' | password_hash('sha512') }}" shell: /bin/zsh tasks: - name: Criar múltiplos usuários com configurações específicas user: name: "{{ item.nome }}" password: "{{ item.senha }}" shell: "{{ item.shell }}" state: present loop: "{{ usuarios }}"
- Explicação:
loop: "{{ usuarios }}": Itera sobre a lista deusuarios.- Cada usuário tem um
nome,senha, eshelldefinidos individualmente.
- Explicação:
Exemplo Prático: Instalação de Pacotes e Configuração de Múltiplos Serviços
O exemplo abaixo mostra um playbook que instala pacotes, configura arquivos e cria usuários, usando loops para otimizar o processo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
--- - name: Configuração Completa de Servidores hosts: all become: yes vars: pacotes_necessarios: - nginx - git - curl usuarios: - nome: carlos senha: "{{ 'senhaCarlos' | password_hash('sha512') }}" shell: /bin/bash - nome: debora senha: "{{ 'senhaDebora' | password_hash('sha512') }}" shell: /bin/zsh tasks: - name: Instalar pacotes essenciais apt: name: "{{ item }}" state: present loop: "{{ pacotes_necessarios }}" when: ansible_os_family == "Debian" - name: Configurar diretório de arquivos temporários file: path: "/tmp/{{ item }}" state: directory loop: - logs - backups - temp - name: Criar usuários com configurações personalizadas user: name: "{{ item.nome }}" password: "{{ item.senha }}" shell: "{{ item.shell }}" state: present loop: "{{ usuarios }}"
- Explicação do Exemplo:
- Pacotes: Instala pacotes essenciais, utilizando um loop com a lista
pacotes_necessarios. - Diretórios: Configura três diretórios (
logs,backups,temp) dentro de/tmp. - Usuários: Cria usuários personalizados com nome, senha criptografada e shell preferido.
- Pacotes: Instala pacotes essenciais, utilizando um loop com a lista
- Explicação do Exemplo:
Tabela de Referência: Principais Opções de Loops no Ansible
Diretiva Função Exemplo loopIteração simples sobre listas e variáveis complexas loop: "{{ lista_de_itens }}"with_itemsItera sobre listas de valores with_items: - item1 - item2with_dictItera sobre pares chave-valor em dicionários with_dict: dict_variavelitem.keyAcessa a chave em um par chave-valor ( with_dict)name: "{{ item.key }}"item.valueAcessa o valor em um par chave-valor ( with_dict)password: "{{ item.value }}"
Resumo
O uso de loops no Ansible permite simplificar e otimizar o código, eliminando a necessidade de duplicação de tarefas para ações repetitivas. Com loop, with_items e with_dict, é possível realizar operações em massa, tornando a execução de playbooks mais eficiente e escalável.
Na próxima seção, vamos explorar o uso de filtros no Ansible para manipulação de variáveis, ajudando a adaptar e transformar dados diretamente no playbook.
6. Uso de Filtros para Manipulação de Variáveis
Objetivo
Explicar como usar filtros do Jinja2 para manipular e transformar dados em variáveis do Ansible, proporcionando mais flexibilidade e evitando erros comuns de formatação.
Conteúdo
Introdução aos Filtros no Ansible
No Ansible, os filtros Jinja2 são utilizados para modificar o valor de variáveis, aplicando transformações ou operações que ajustem os dados conforme necessário. Os filtros ajudam a padronizar valores, gerenciar strings e garantir que as variáveis atendam a determinados requisitos antes da execução da tarefa.
Aplicação Básica de Filtros em Playbooks
Filtros são aplicados a variáveis usando a sintaxe
{{ variavel | filtro }}, ondefiltroé o nome do filtro aplicado à variável.Exemplo de Filtros Básicos:
| lower: Converte uma string para letras minúsculas.| upper: Converte uma string para letras maiúsculas.| default: Define um valor padrão caso a variável não esteja definida.
1 2 3 4 5 6 7 8 9 10 11 12 13
vars: nome_usuario: "Carlos" arquivo_log: "" tasks: - name: Criar diretório para o usuário em minúsculas file: path: "/home/{{ nome_usuario | lower }}" state: directory - name: Definir arquivo de log padrão se não especificado debug: msg: "Arquivo de log: {{ arquivo_log | default('/var/log/default.log') }}"
- Explicação:
{{ nome_usuario | lower }}: ConverteCarlosparacarlos, criando o diretório/home/carlos.{{ arquivo_log | default('/var/log/default.log') }}: Usa o valor padrão/var/log/default.logcasoarquivo_lognão esteja definido.
Manipulação de Strings com Filtros
Para operações com strings, os filtros podem realizar substituições, remoção de caracteres ou validações de formatação.
Exemplo: Substituir e Remover Caracteres com
replaceetrim1 2 3 4 5 6 7 8
vars: nome_arquivo: "backup " extensao: "txt" tasks: - name: Substituir extensão do arquivo debug: msg: "{{ nome_arquivo | trim }}.{{ extensao | replace('txt', 'log') }}"
- Explicação:
trim: Remove espaços em branco extras na variávelnome_arquivo.replace('txt', 'log'): Substitui.txtpor.logna variávelextensao.
- Explicação:
Filtros Numéricos e Lógicos para Controle de Valores
Filtros como
interoundsão úteis para manipular números. Eles podem converter strings numéricas em inteiros ou arredondar valores, facilitando cálculos e validações de requisitos.Exemplo de Uso de Filtros Numéricos:
1 2 3 4 5 6 7 8 9
vars: cpu_requerida: "2.5" cpu_disponivel: 4 tasks: - name: Verificar se a CPU disponível atende o requisito debug: msg: "CPU atende o requisito" when: cpu_disponivel >= (cpu_requerida | float | round(0, 'ceil'))
- Explicação:
float: Convertecpu_requeridaem um número decimal para comparação.round(0, 'ceil'): Arredondacpu_requeridapara cima, garantindo que a comparação seja precisa.
- Explicação:
Filtros de Listas e Dicionários para Estruturas Complexas
O Ansible também permite aplicar filtros a listas e dicionários, facilitando operações como ordenação e busca de elementos específicos.
Exemplo de Ordenação e Busca em Listas:
1 2 3 4 5 6 7 8 9 10 11
vars: usuarios: - "carlos" - "ana" - "beatriz" - "joao" tasks: - name: Exibir lista de usuários em ordem alfabética debug: msg: "{{ usuarios | sort }}"
- Explicação:
sort: Ordena a lista deusuariosem ordem alfabética.
- Explicação:
Exemplo Prático de Uso de Filtros para Configuração Personalizada
No exemplo abaixo, o playbook utiliza filtros para criar um diretório com o nome do usuário em letras minúsculas e definir uma configuração de log padrão.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
--- - name: Configuração do Servidor com Filtros hosts: all become: yes vars: usuario: "Carlos" porta: "8080" caminho_log: "" tasks: - name: Criar diretório do usuário em minúsculas file: path: "/home/{{ usuario | lower }}" state: directory - name: Configurar porta padrão lineinfile: path: /etc/myapp/config.cfg regexp: 'port=' line: "port={{ porta | int }}" - name: Definir arquivo de log padrão se vazio debug: msg: "Caminho do log: {{ caminho_log | default('/var/log/myapp.log') }}"
- Explicação do Exemplo:
usuario | lower: Garante que o diretório seja criado com o nome do usuário em minúsculas.porta | int: Converte a porta para um número inteiro, assegurando que esteja no formato correto.caminho_log | default('/var/log/myapp.log'): Define um caminho de log padrão se o valor estiver vazio.
- Explicação do Exemplo:
Tabela de Referência dos Filtros Comuns
Filtro Função Exemplo lowerConverte string para minúsculas {{ nome | lower }}upperConverte string para maiúsculas {{ nome | upper }}defaultDefine um valor padrão {{ valor | default('padrão') }}replaceSubstitui valores na string {{ texto | replace('a', 'e') }}int/floatConverte para inteiro ou decimal {{ valor | int }}sortOrdena uma lista {{ lista | sort }}roundArredonda números {{ numero | round(0, 'ceil') }}trimRemove espaços em branco da string {{ texto | trim }}
Resumo
Filtros no Ansible fornecem uma forma eficiente de manipular variáveis, garantindo que os dados estejam no formato correto e que os playbooks sejam mais flexíveis e robustos. Com filtros como default, replace, sort, e int, é possível ajustar variáveis conforme a necessidade, evitando erros comuns de formatação e validação.
Na próxima seção, vamos explorar o uso de condicionais com when para executar tarefas apenas em condições específicas, tornando os playbooks ainda mais adaptáveis a diferentes cenários e ambientes.
7. Condicionais com when para Controle de Execução
Objetivo
Demonstrar como usar a diretiva when para controlar a execução condicional de tarefas no Ansible, permitindo uma maior adaptabilidade dos playbooks para diferentes cenários e ambientes.
Conteúdo
Introdução ao Uso de Condicionais com
whenA diretiva
whenpermite que uma tarefa seja executada somente se uma condição for verdadeira. Isso possibilita a criação de playbooks mais inteligentes, adaptando-os a diferentes sistemas operacionais, versões de software e ambientes. As condições são expressas em expressões Jinja2, que podem incluir comparações e combinações de variáveis.Exemplo Simples de Condição
when:1 2 3 4 5 6
tasks: - name: Instalar Nginx em sistemas Debian apt: name: nginx state: present when: ansible_os_family == "Debian"
- Explicação:
- A tarefa de instalação do Nginx será executada apenas se o host pertencer à família de sistemas
Debian.
- A tarefa de instalação do Nginx será executada apenas se o host pertencer à família de sistemas
- Explicação:
Usando Condicionais para Diferentes Sistemas Operacionais
Condicionais são especialmente úteis ao criar playbooks para múltiplos sistemas operacionais. Abaixo, vemos um exemplo de instalação do Nginx que verifica o sistema operacional e adapta o módulo (
aptpara Debian eyumpara Red Hat).Exemplo de Condicionais para Instalação em Diferentes Sistemas:
1 2 3 4 5 6 7 8 9 10 11 12
tasks: - name: Instalar Nginx em Debian apt: name: nginx state: present when: ansible_os_family == "Debian" - name: Instalar Nginx em Red Hat yum: name: nginx state: present when: ansible_os_family == "RedHat"
- Explicação:
- A primeira tarefa é executada apenas em sistemas Debian, enquanto a segunda é executada apenas em sistemas Red Hat.
- Explicação:
Combinação de Condições Usando Operadores Lógicos
Você pode combinar múltiplas condições usando operadores lógicos (
and,or,not). Isso ajuda a especificar cenários mais complexos e a adaptar o comportamento do playbook a requisitos específicos.Exemplo: Condição Baseada em Sistema e Versão:
1 2 3 4 5 6
tasks: - name: Instalar uma versão específica do MySQL em Debian 10 apt: name: mysql-server state: present when: ansible_os_family == "Debian" and ansible_distribution_version == "10"
- Explicação:
- A tarefa é executada apenas em hosts Debian que estejam na versão 10.
- Explicação:
Uso de Variáveis e Filtros em Condicionais
É possível utilizar variáveis e filtros para tornar as condições ainda mais dinâmicas, como verificar a presença de um valor específico antes de executar a tarefa.
Exemplo: Executar Tarefa Somente se Variável Estiver Definida e em Maiúsculas
1 2 3 4 5 6 7 8 9
vars: nome_arquivo: "" tasks: - name: Criar arquivo se o nome estiver definido e em maiúsculas file: path: "/tmp/{{ nome_arquivo }}" state: touch when: nome_arquivo | default("") | upper == nome_arquivo
- Explicação:
- A tarefa será executada apenas se
nome_arquivoestiver definido e em letras maiúsculas.
- A tarefa será executada apenas se
- Explicação:
Controle Condicional para Grupos e Tags de Hosts
Além de variáveis e sistema operacional, as condições também podem ser aplicadas com base nos grupos ou tags definidas para os hosts, permitindo uma configuração ainda mais segmentada.
Exemplo: Executar Tarefa Apenas em Servidores com a Tag
webserver1 2 3 4 5
tasks: - name: Atualizar pacotes em servidores web apt: upgrade: dist when: "'webserver' in group_names"
- Explicação:
- A tarefa será executada apenas se o host pertencer ao grupo
webserver.
- A tarefa será executada apenas se o host pertencer ao grupo
- Explicação:
Exemplo Prático de Controle Condicional no Playbook
No exemplo a seguir, o playbook configura o Apache em diferentes distribuições Linux e ajusta o firewall apenas se o sistema suportar o
ufw.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
--- - name: Configuração Condicional de Servidor Web hosts: webservers become: yes tasks: - name: Instalar Apache em Debian apt: name: apache2 state: present when: ansible_os_family == "Debian" - name: Instalar Apache em Red Hat yum: name: httpd state: present when: ansible_os_family == "RedHat" - name: Configurar firewall se o UFW estiver disponível ufw: rule: allow name: "Apache" when: ansible_facts['pkg_mgr'] == "apt"
- Explicação do Exemplo:
- A primeira tarefa instala o Apache em Debian e a segunda, em Red Hat, utilizando módulos específicos.
- A última tarefa configura o firewall
ufwapenas em sistemas Debian, ondeufwé suportado.
- Explicação do Exemplo:
Tabela de Referência: Operadores e Sintaxe para
whenOperador Descrição Exemplo ==Igual a ansible_os_family == "Debian"!=Diferente de ansible_os_family != "RedHat"andTodas as condições devem ser verdadeiras condicao1 and condicao2orPelo menos uma condição deve ser verdadeira condicao1 or condicao2notInverte a condição not condicaoinVerifica a existência em uma lista "'web' in group_names"
Resumo
As condicionais when no Ansible tornam os playbooks mais flexíveis e adaptáveis a diferentes cenários e ambientes. Usando when com operadores lógicos, variáveis e filtros, você pode controlar com precisão a execução de tarefas, garantindo que elas ocorram apenas em situações específicas.
Na próxima seção, exploraremos o uso de blocos (block) e tratamento de erros com rescue, facilitando o controle de execução e a recuperação de erros durante a execução dos playbooks.
8. Uso de Blocos (block) e Tratamento de Erros com rescue
Objetivo
Explicar como agrupar tarefas com block e gerenciar erros com rescue, criando um fluxo de execução que permite tratamento de falhas e recuperação de tarefas no Ansible.
Conteúdo
Introdução ao Uso de Blocos (
block)O Ansible permite agrupar tarefas em blocos (
block), o que facilita a organização de tarefas e o controle de execuções específicas. Comblock, você pode aplicar condicionais e permissões a um grupo inteiro de tarefas, simplificando a estrutura do playbook. Além disso,blockpermite definir ações derescue(para quando ocorre um erro) ealways(executado sempre, independentemente de erros).Exemplo Básico de
block:1 2 3 4 5 6 7 8 9 10
tasks: - block: - name: Instalar pacotes necessários apt: name: "{{ item }}" state: present loop: - nginx - git when: ansible_os_family == "Debian"
- Explicação:
- O bloco é executado apenas se a condição
ansible_os_family == "Debian"for verdadeira, aplicando a condição a todas as tarefas internas.
- O bloco é executado apenas se a condição
- Explicação:
Tratamento de Erros com
rescueO
rescueé um bloco que define tarefas a serem executadas quando ocorre um erro em alguma das tarefas doblock. Isso é útil para tentar outras alternativas ou realizar ações corretivas em caso de falha.Exemplo de Uso de
rescuepara Alternativa de Instalação1 2 3 4 5 6 7 8 9
tasks: - block: - name: Tentar instalar o pacote do repositório oficial apt: name: nginx state: present rescue: - name: Tentar instalação manual command: wget -q -O- http://nginx.org/keys/nginx_signing.key | apt-key add -
- Explicação:
- Se a instalação do
nginxfalhar, o blocorescuetenta instalar o pacote a partir de uma chave externa.
- Se a instalação do
- Explicação:
Execução Incondicional com
alwaysO
alwaysdefine tarefas que devem ser executadas independentemente do sucesso ou falha das tarefas anteriores. Ele é útil para tarefas de limpeza, envio de logs ou notificações.Exemplo de Uso de
alwayspara Limpeza Após Tentativas1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
tasks: - block: - name: Instalar pacotes críticos apt: name: "{{ item }}" state: present loop: - apache2 - mysql-server rescue: - name: Registrar falha de instalação debug: msg: "Falha na instalação dos pacotes críticos" always: - name: Limpar cache de pacotes command: apt-get clean
- Explicação:
- Se a instalação falhar, a tarefa de
rescueregistra a falha. - Independente do resultado,
alwayslimpa o cache de pacotes.
- Se a instalação falhar, a tarefa de
- Explicação:
Exemplo Prático de Uso de
block,rescueealwayspara Recuperação de ErrosO exemplo abaixo configura um servidor web e tenta corrigir a instalação caso ela falhe, registrando o status final no final.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
--- - name: Configuração Completa do Servidor Web com Tratamento de Erros hosts: webservers become: yes tasks: - block: - name: Instalar Nginx apt: name: nginx state: present - name: Copiar configuração do Nginx copy: src: /local/path/nginx.conf dest: /etc/nginx/nginx.conf notify: Reiniciar Nginx rescue: - name: Tentar outra versão do Nginx apt: name: nginx=1.18.* state: present - name: Registrar falha na instalação padrão debug: msg: "Instalação padrão do Nginx falhou, tentando versão alternativa." always: - name: Verificar status do Nginx service: name: nginx state: started handlers: - name: Reiniciar Nginx service: name: nginx state: restarted
- Explicação do Exemplo:
- O bloco
blockexecuta a instalação e configuração do Nginx. - Se a instalação falhar, o
rescuetenta instalar uma versão alternativa e registra a tentativa. - O
alwaysgarante que o serviço Nginx seja iniciado após a execução das tarefas.
- O bloco
- Explicação do Exemplo:
Tabela de Referência dos Elementos de Controle em Blocos
Elemento Função Exemplo blockAgrupa tarefas e aplica condições a todas elas - block: - name: Instalar ...rescueExecuta tarefas alternativas se houver erro nas tarefas do blockrescue: - name: Tentar alternativa ...alwaysExecuta tarefas independentemente do sucesso ou falha always: - name: Limpar cache
Resumo
Com block, rescue, e always, você pode organizar tarefas e definir fluxos alternativos para recuperação de erros, garantindo que seu playbook seja resiliente e adaptável a diferentes condições e falhas. Essas funcionalidades permitem maior controle sobre o fluxo de execução e são essenciais para a robustez de playbooks em ambientes complexos.
Na próxima seção, veremos como modularizar tarefas usando include e import_tasks, facilitando a organização de playbooks maiores e a reutilização de tarefas em diferentes cenários.
9. Uso de Arquivos Include e Modularização com import_tasks
Objetivo
Demonstrar como modularizar tarefas com include e import_tasks no Ansible, organizando tarefas em arquivos separados e facilitando a reutilização em playbooks complexos.
Conteúdo
Por que Modularizar Tarefas?
Em playbooks complexos, modularizar tarefas melhora a legibilidade, facilita a manutenção e permite reutilizar tarefas em diferentes cenários. Com
includeeimport_tasks, é possível separar funcionalidades específicas em arquivos distintos, que podem ser incluídos ou importados conforme necessário no playbook principal.Diferença entre
include_taskseimport_tasksinclude_tasks: Inclui tarefas dinamicamente durante a execução, permitindo controle condicional (when) ou uso de loops. A inclusão é processada em tempo de execução.import_tasks: Importa tarefas de forma estática e imediata, semelhante a copiar o conteúdo do arquivo para o playbook no momento da execução.
Resumo:
include_tasksé processado durante a execução e permite condições dinâmicas.import_tasksé processado no início e não permite ajustes dinâmicos durante a execução.
Exemplo de Uso de
include_taskscom CondicionalEstrutura de Arquivos:
1 2 3 4
├── playbook.yml ├── tasks/ │ ├── instalar_apache.yml │ └── instalar_nginx.yml
instalar_apache.yml:1 2 3 4
- name: Instalar Apache apt: name: apache2 state: present
instalar_nginx.yml:1 2 3 4
- name: Instalar Nginx apt: name: nginx state: present
Playbook principal (
playbook.yml):1 2 3 4 5 6 7 8 9 10 11 12 13
--- - name: Configuração Condicional do Servidor Web hosts: webservers become: yes tasks: - name: Incluir tarefas para Apache include_tasks: tasks/instalar_apache.yml when: ansible_os_family == "Debian" and web_server == "apache" - name: Incluir tarefas para Nginx include_tasks: tasks/instalar_nginx.yml when: ansible_os_family == "Debian" and web_server == "nginx"
Explicação:
- As tarefas de instalação do Apache e Nginx foram movidas para arquivos distintos na pasta
tasks. - O playbook principal inclui cada arquivo de tarefa com
include_tasks, condicionado à variávelweb_server, permitindo a escolha dinâmica entre Apache e Nginx.
- As tarefas de instalação do Apache e Nginx foram movidas para arquivos distintos na pasta
Uso de
import_taskspara Importação EstáticaEstrutura de Arquivos:
1 2 3 4
├── playbook.yml ├── tasks/ │ ├── config_apache.yml │ └── config_nginx.yml
config_apache.yml:1 2 3 4
- name: Configurar Apache lineinfile: path: /etc/apache2/apache2.conf line: "Timeout 300"
config_nginx.yml:1 2 3 4
- name: Configurar Nginx lineinfile: path: /etc/nginx/nginx.conf line: "keepalive_timeout 65"
Playbook principal (
playbook.yml):1 2 3 4 5 6 7 8 9 10 11
--- - name: Importar Configuração do Servidor Web hosts: webservers become: yes tasks: - import_tasks: tasks/config_apache.yml when: web_server == "apache" - import_tasks: tasks/config_nginx.yml when: web_server == "nginx"
Explicação:
import_taskscarrega as tarefas de configuração para Apache ou Nginx de forma estática.- A execução condicional com
whendefine qual configuração será aplicada.
Organização Modular para Estruturas Complexas
Modularizar tarefas torna playbooks complexos mais gerenciáveis. Uma estrutura de diretórios bem organizada pode ajudar a manter o projeto limpo e intuitivo.
Exemplo de Estrutura Modular:
1 2 3 4 5 6 7 8 9 10 11 12
├── site.yml # Playbook principal ├── webservers.yml # Playbook para servidores web ├── dbservers.yml # Playbook para servidores de banco de dados ├── tasks/ │ ├── install/ │ │ ├── apache.yml │ │ └── nginx.yml │ ├── config/ │ │ ├── apache_config.yml │ │ └── nginx_config.yml └── handlers/ └── restart_services.yml # Handlers centralizados para reiniciar serviços- Explicação:
- Arquivos de instalação (
install/) e configuração (config/) são organizados por tipo de serviço. handlers/restart_services.ymlcontém handlers centralizados para reiniciar serviços, reutilizáveis em diferentes playbooks.
- Arquivos de instalação (
- Explicação:
Exemplo Completo de Modularização com
include_taskseimport_tasksO exemplo a seguir usa
include_taskspara incluir uma tarefa de instalação eimport_taskspara aplicar uma configuração específica, com um handler centralizado para reiniciar o serviço.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
--- - name: Configuração Modular do Servidor Web hosts: webservers become: yes tasks: - name: Incluir instalação de Apache ou Nginx include_tasks: "tasks/install/{{ web_server }}.yml" when: ansible_os_family == "Debian" - name: Importar configuração de Apache ou Nginx import_tasks: "tasks/config/{{ web_server }}_config.yml" when: ansible_os_family == "Debian" handlers: - import_tasks: handlers/restart_services.yml
- Explicação:
- A tarefa
include_tasksinclui dinamicamente o arquivo de instalação de acordo com o valor da variávelweb_server. - A tarefa
import_taskscarrega a configuração para o servidor web especificado. - Handlers são centralizados e importados de
restart_services.yml, mantendo o playbook principal mais limpo.
- A tarefa
- Explicação:
Tabela de Referência para Modularização com
include_taskseimport_tasksDiretiva Descrição Exemplo de Uso include_tasksInclui tarefas dinamicamente, permitindo condicionais e loops include_tasks: tasks/config_nginx.ymlimport_tasksImporta tarefas estaticamente, sem ajustes dinâmicos durante execução import_tasks: tasks/install_nginx.ymlHandlers Pode ser centralizado e incluído para múltiplos playbooks - import_tasks: handlers/restart_services.yml
Resumo
O uso de include_tasks e import_tasks permite modularizar playbooks no Ansible, criando uma estrutura organizada, legível e fácil de manter. Com essa abordagem, é possível dividir tarefas complexas em arquivos menores, reutilizar componentes e tornar o gerenciamento de grandes ambientes mais eficiente.
Na próxima seção, vamos explorar o uso de roles, uma funcionalidade avançada para organizar playbooks em componentes reutilizáveis e modularizados.
10. Estrutura e Uso de Roles em Playbooks
Objetivo
Explicar como organizar e reutilizar configurações complexas com roles, permitindo que playbooks sejam mais modulares e reutilizáveis.
Conteúdo
Introdução às Roles
Roles são componentes modulares e reutilizáveis no Ansible, usadas para organizar tarefas, variáveis, handlers, templates e arquivos necessários para configurar uma aplicação ou serviço específico. As roles facilitam a manutenção e permitem compartilhar configurações em múltiplos playbooks ou ambientes.
Principais Características das Roles:
- Estrutura organizada que separa tarefas, handlers, arquivos, templates e variáveis.
- Reutilizáveis em diferentes projetos, ambientes e playbooks.
- Facilitam a colaboração e o compartilhamento de configurações.
Estrutura de Diretórios de uma Role
A estrutura padrão de uma role é organizada em diretórios específicos, onde cada um possui uma função bem definida. Ao criar uma role, o Ansible organiza automaticamente os diretórios da seguinte forma:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
└── nome_da_role/ ├── defaults/ # Variáveis padrão │ └── main.yml ├── files/ # Arquivos estáticos ├── handlers/ # Handlers para notificações │ └── main.yml ├── meta/ # Metadados da role (dependências) │ └── main.yml ├── tasks/ # Tarefas principais │ └── main.yml ├── templates/ # Templates (arquivos Jinja2) ├── vars/ # Variáveis personalizadas │ └── main.yml └── README.md # Documentação da role- defaults: Define variáveis padrão, que podem ser sobrescritas.
- files: Contém arquivos a serem copiados para os hosts.
- handlers: Define handlers que podem ser chamados por tarefas.
- meta: Contém metadados, como dependências de outras roles.
- tasks: Diretório onde as tarefas principais são definidas (arquivo
main.yml). - templates: Armazena templates Jinja2.
- vars: Define variáveis específicas da role, com maior precedência que
defaults.
Criando uma Role com o Comando
ansible-galaxyO Ansible facilita a criação de roles com o comando
ansible-galaxy init, que gera automaticamente a estrutura de diretórios necessária.Comando para Criar uma Role:
1
ansible-galaxy init nome_da_role
Exemplo:
1
ansible-galaxy init apache
- Isso criará uma pasta
apachecom toda a estrutura padrão para a role de configuração do Apache.
- Isso criará uma pasta
Configurando Tarefas e Variáveis em uma Role
Para definir as tarefas e variáveis principais de uma role, você deve configurar os arquivos no diretório
tasksevars.Exemplo de Role para Configuração do Apache:
tasks/main.yml:
1 2 3 4 5 6 7 8 9 10 11 12
--- - name: Instalar o Apache apt: name: apache2 state: present notify: Reiniciar Apache - name: Copiar arquivo de configuração do Apache template: src: apache2.conf.j2 dest: /etc/apache2/apache2.conf notify: Reiniciar Apache
handlers/main.yml:
1 2 3 4 5
--- - name: Reiniciar Apache service: name: apache2 state: restarted
templates/apache2.conf.j2:
1 2
# Configuração do Apache ServerName {{ ansible_hostname }}defaults/main.yml:
1 2
--- apache_port: 80
Explicação:
- As tarefas instalam o Apache e copiam o arquivo de configuração personalizado.
- Um template
apache2.conf.j2usa a variávelansible_hostnamepara definir oServerName. - Um handler reinicia o Apache quando notificado após mudanças.
Usando Roles em Playbooks
Uma vez criada, a role pode ser incluída em qualquer playbook com a diretiva
roles. Isso permite aplicar a role aos hosts definidos no playbook de maneira simples.Exemplo de Playbook Usando a Role
apache:1 2 3 4 5 6
--- - name: Configuração de Servidores Web hosts: webservers become: yes roles: - apache
- Explicação:
- O playbook aplica a role
apacheem todos os hosts do grupowebservers.
- O playbook aplica a role
- Explicação:
Usando Dependências de Roles com
meta/main.ymlNo arquivo
meta/main.ymlda role, você pode definir dependências de outras roles, fazendo com que o Ansible carregue automaticamente roles adicionais conforme necessário.Exemplo de Dependências em
meta/main.yml:1 2 3 4 5 6 7
--- dependencies: - role: firewall vars: firewall_ports: - "80" - "443"
- Explicação:
- Define que a role
firewalldeve ser aplicada antes da role atual, com a configuração de variáveis adicionais.
- Define que a role
- Explicação:
Exemplo Completo de Uso de Roles para Configuração de Servidores Web
Este exemplo mostra um playbook que usa duas roles,
apacheefirewall, para configurar um servidor web seguro.1 2 3 4 5 6 7 8 9 10 11 12
--- - name: Configuração Completa do Servidor Web hosts: webservers become: yes roles: - role: apache - role: firewall vars: firewall_ports: - "80" - "443"
- Explicação:
- A role
apacheinstala e configura o Apache. - A role
firewallabre as portas 80 e 443, garantindo que o servidor esteja acessível.
- A role
- Explicação:
Tabela de Referência para Estrutura de Roles
Diretório Função Exemplo de Conteúdo tasksDefine as tarefas principais da role tasks/main.ymlhandlersDefine handlers para notificações handlers/main.ymlvarsVariáveis específicas da role vars/main.ymldefaultsVariáveis padrão, substituíveis defaults/main.ymlfilesArmazena arquivos estáticos files/index.htmltemplatesArmazena templates Jinja2 para personalização dinâmica templates/apache2.conf.j2metaDefine metadados e dependências meta/main.yml
Resumo
Roles são uma das melhores práticas para organizar e reutilizar configurações no Ansible. Com uma estrutura organizada de diretórios, roles permitem encapsular a lógica de configuração de serviços específicos e compartilhar essas configurações em múltiplos playbooks e ambientes.
Na próxima seção, abordaremos práticas de segurança em playbooks, garantindo a proteção de senhas, credenciais e informações sensíveis com o uso do vault do Ansible e outras práticas recomendadas.
11. Segurança em Playbooks
Objetivo
Apresentar práticas recomendadas de segurança para proteger informações sensíveis em playbooks, como senhas, chaves SSH e variáveis críticas. Isso inclui o uso de Ansible Vault e outras técnicas para proteger dados em ambientes de produção.
Conteúdo
Introdução à Segurança em Playbooks
Segurança é essencial no uso de playbooks, especialmente quando incluem informações sensíveis como senhas, chaves API e credenciais. O Ansible fornece o
Ansible Vaultpara criptografar dados críticos e manter a segurança em playbooks compartilhados entre equipes ou armazenados em repositórios.Protegendo Informações com
Ansible VaultO
Ansible Vaulté uma ferramenta integrada ao Ansible que permite criptografar arquivos e variáveis, garantindo que dados sensíveis fiquem protegidos. É possível usá-lo para proteger variáveis, arquivos de configuração e até playbooks inteiros.Comando para Criar um Arquivo Criptografado com
Vault:1
ansible-vault create secrets.yml
Esse comando abre um editor de texto para você inserir variáveis e outros dados sensíveis. Ao salvar e fechar o editor, o conteúdo será criptografado.
Exemplo de Variáveis em
secrets.yml:1 2
db_password: super_secreta123 api_key: abcd1234apikey
Editando e Exibindo Arquivos Criptografados com
VaultEditar: Para modificar um arquivo criptografado, use o comando:
1
ansible-vault edit secrets.yml
Exibir: Para visualizar o conteúdo de um arquivo criptografado, use:
1
ansible-vault view secrets.yml
Usando Arquivos Criptografados em Playbooks
Uma vez criado o arquivo criptografado, você pode incluí-lo diretamente no playbook usando
vars_files. Ao executar o playbook, forneça a senha do Vault para descriptografar as variáveis.Exemplo de Playbook com
vars_filesCriptografado:1 2 3 4 5 6 7 8 9 10 11 12 13
--- - name: Configuração do Banco de Dados com Segurança hosts: dbservers become: yes vars_files: - secrets.yml tasks: - name: Configurar o banco de dados mysql_user: name: appuser password: "{{ db_password }}" state: present
Executando o Playbook com
Vault:1
ansible-playbook playbook.yml --ask-vault-pass- Explicação:
--ask-vault-pass: Solicita a senha para descriptografarsecrets.ymldurante a execução.
- Explicação:
Recriptografando e Alterando a Senha do Vault
Para recriptografar um arquivo com uma nova senha, use o comando
rekey:1
ansible-vault rekey secrets.yml
Uso de Variáveis Ambientais para Segurança Adicional
Variáveis ambientais são outra forma de proteger dados sensíveis, especialmente em integrações de CI/CD onde a senha do Vault é configurada diretamente no ambiente, evitando exposição em scripts ou arquivos.
Exemplo: Usar Variável de Ambiente para a Senha do Vault
1
export ANSIBLE_VAULT_PASSWORD_FILE=~/.vault_pass
- Explicação:
ANSIBLE_VAULT_PASSWORD_FILE: Define um arquivo com a senha do Vault, evitando inserir a senha manualmente a cada execução.
- Explicação:
Práticas de Segurança no Uso de Chaves SSH e Credenciais
Além do Vault, o Ansible oferece boas práticas para proteger o uso de chaves SSH e outras credenciais.
- Armazene Chaves SSH em Diretórios Protegidos: As chaves privadas devem estar em diretórios com permissões restritas e não devem ser incluídas diretamente no playbook.
- Use SSH Agent para Carregar Chaves: Carregar chaves SSH no
ssh-agentevita que as credenciais fiquem expostas. - Evite Variáveis Sensíveis em
group_varsehost_vars: Variáveis sensíveis devem ser mantidas em arquivos criptografados com Vault em vez degroup_varsehost_vars.
Exemplo Completo de Playbook com
Vaulte Boas Práticas de SegurançaO exemplo a seguir mostra um playbook que configura o banco de dados e usa variáveis criptografadas para proteger a senha do banco.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
--- - name: Configuração Segura do Banco de Dados hosts: dbservers become: yes vars_files: - secrets.yml tasks: - name: Criar usuário de banco de dados mysql_user: name: dbuser password: "{{ db_password }}" priv: "*.*:ALL" state: present - name: Configurar parâmetros de segurança lineinfile: path: /etc/mysql/my.cnf regexp: '^bind-address' line: 'bind-address = 127.0.0.1' notify: Reiniciar MySQL handlers: - name: Reiniciar MySQL service: name: mysql state: restarted
- Explicação:
- A senha do usuário do banco (
db_password) está armazenada no arquivosecrets.yml, criptografado comVault. - Um handler reinicia o MySQL após a alteração da configuração.
- A senha do usuário do banco (
- Explicação:
Tabela de Referência: Comandos do Ansible Vault
Comando Descrição Exemplo ansible-vault createCria um novo arquivo criptografado ansible-vault create secrets.ymlansible-vault editEdita um arquivo criptografado ansible-vault edit secrets.ymlansible-vault viewExibe o conteúdo de um arquivo criptografado ansible-vault view secrets.ymlansible-vault encryptCriptografa um arquivo existente ansible-vault encrypt vars.ymlansible-vault decryptDescriptografa um arquivo existente ansible-vault decrypt vars.ymlansible-vault rekeyRecriptografa um arquivo com nova senha ansible-vault rekey secrets.yml
Resumo
Garantir a segurança em playbooks é essencial para proteger dados críticos, especialmente em ambientes de produção. O Ansible Vault fornece criptografia para variáveis e arquivos sensíveis, enquanto variáveis de ambiente e práticas seguras no uso de chaves SSH reforçam a proteção dos dados. Com essas práticas, é possível automatizar tarefas no Ansible com segurança, minimizando o risco de exposição de informações confidenciais.
Na próxima seção, vamos explorar ferramentas de debugging e testes, incluindo ansible-lint e molecule, que ajudam a verificar a qualidade e a funcionalidade dos playbooks antes da execução em ambientes de produção.
12. Ferramentas de Debugging e Testes
Objetivo
Apresentar ferramentas para verificação, validação e testes de playbooks no Ansible, permitindo identificar problemas e garantir que os playbooks atendam às melhores práticas e funcionem corretamente em ambientes de produção.
Conteúdo
Introdução à Importância do Debugging e Testes
Debugging e testes são etapas fundamentais para garantir a qualidade dos playbooks. Eles permitem identificar erros de sintaxe, validação de variáveis e possíveis falhas de execução antes de aplicar o playbook em ambientes críticos. O Ansible oferece ferramentas como
ansible-lintpara verificar boas práticas emoleculepara testar playbooks em ambientes simulados.Uso de
ansible-lintpara Verificação de Boas PráticasO
ansible-linté uma ferramenta que verifica os playbooks quanto ao uso de boas práticas e padronizações. Ele analisa o código em busca de problemas comuns, como falta de variáveis padronizadas, uso incorreto de módulos e configurações inseguras.Instalação do
ansible-lint:1
pip install ansible-lintExecutando o
ansible-lintem um Playbook:1
ansible-lint playbook.yml
- Explicação:
- O comando examina o playbook
playbook.ymle lista quaisquer erros ou avisos que violam as melhores práticas.
- O comando examina o playbook
- Explicação:
Mensagens Comuns do
ansible-linte CorreçõesExemplo de Erros e Soluções Comuns:
- Erro: “Use ‘state’ when installing a package.”
- Causa: A ausência de
state(comopresent) ao instalar um pacote. - Correção: Adicionar
state: presentao módulo de instalação de pacotes.
- Causa: A ausência de
- Erro: “No ‘become’ statement in playbook with tasks requiring elevated privileges.”
- Causa: Falta de
become: yesem tarefas que requerem sudo. - Correção: Adicionar
become: yesno play ou nas tarefas.
- Causa: Falta de
- Erro: “Use ‘state’ when installing a package.”
Uso de Debugging em Playbooks com o Módulo
debugO módulo
debugé uma ferramenta útil para exibir valores de variáveis, confirmar saídas e validar informações em tempo de execução, facilitando a depuração e compreensão dos dados que estão sendo processados.Exemplo de Uso do Módulo
debug:1 2 3 4
tasks: - name: Exibir valor da variável db_user debug: msg: "O usuário do banco de dados é: {{ db_user }}"
- Explicação:
- A tarefa exibe o valor da variável
db_userno console durante a execução, permitindo validar seu conteúdo.
- A tarefa exibe o valor da variável
- Explicação:
Testes Automatizados de Playbooks com
moleculeO
moleculeé uma ferramenta avançada para testes de roles e playbooks, permitindo criar ambientes virtuais e testar playbooks em cenários simulados, como contêineres ou máquinas virtuais.Instalação do
molecule:1
pip install molecule[docker]Criando um Novo Teste com
molecule init:1
molecule init role nome_da_role
Esse comando cria a estrutura de testes para a role, incluindo cenários de execução e arquivos de configuração de ambiente.
Executando Testes de Role com
moleculeO
moleculepermite criar e destruir ambientes de teste, executar a role e verificar os resultados. A seguir, os comandos básicos para testar a execução da role em um ambiente simulado.Exemplo de Fluxo de Testes com
molecule:Criar o Ambiente de Teste:
1
molecule create
Aplicar a Role:
1
molecule converge
Executar Testes de Validação:
1
molecule verify
Destruir o Ambiente Após o Teste:
1
molecule destroy
Explicação do Fluxo:
create: Prepara o ambiente de teste (como um contêiner Docker ou máquina virtual).converge: Aplica a role no ambiente.verify: Executa testes de validação (usualmente scripts de verificação).destroy: Remove o ambiente após a execução dos testes.
Integração com Testes Automatizados de CI/CD
Integrar
ansible-lintemoleculeem pipelines de CI/CD ajuda a garantir que as modificações em playbooks ou roles sejam testadas e validadas antes de serem implementadas em produção.Exemplo de Pipeline de CI/CD Simples com Lint e Testes:
1 2 3 4 5 6 7 8 9 10 11
stages: - lint - test lint: script: - ansible-lint playbook.yml test: script: - molecule test
- Explicação:
- A primeira etapa (
lint) executa oansible-lintpara verificar as boas práticas. - A segunda etapa (
test) executa os testes domoleculepara validar a role.
- A primeira etapa (
- Explicação:
Exemplo Completo de um Playbook com
debuge TestesO exemplo abaixo mostra um playbook com tarefas para configurar um banco de dados, usando
debugpara exibir o nome do banco de dados e uma configuração demoleculepara testes da role.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
--- - name: Configuração do Banco de Dados com Debug hosts: dbservers become: yes vars: db_name: exemplo_db db_user: exemplo_user tasks: - name: Criar banco de dados mysql_db: name: "{{ db_name }}" state: present - name: Exibir nome do banco de dados debug: msg: "Banco de dados configurado: {{ db_name }}"
Configuração de Teste com Molecule:
1 2 3 4 5 6 7 8
# molecule/default/molecule.yml driver: name: docker platforms: - name: instance image: geerlingguy/docker-debian10-ansible pre_build_image: true
- Explicação:
- O playbook usa
debugpara exibir o nome do banco de dados configurado. - A configuração
molecule.ymldefine uma plataforma Docker com Debian para teste.
- O playbook usa
- Explicação:
Tabela de Referência: Comandos de Debugging e Testes
Comando Descrição Exemplo ansible-lintVerifica o playbook quanto a boas práticas ansible-lint playbook.ymldebugExibe informações de variáveis e mensagens debug: msg: "Valor: {{ variavel }}"molecule createCria o ambiente de teste molecule createmolecule convergeAplica a role no ambiente de teste molecule convergemolecule verifyExecuta os testes de validação molecule verifymolecule destroyDestrói o ambiente de teste após a execução molecule destroy
Resumo
Ferramentas de debugging e testes como ansible-lint e molecule ajudam a garantir a qualidade e segurança dos playbooks antes de sua execução em produção. Usar debug facilita o diagnóstico de variáveis, enquanto o molecule oferece um ambiente seguro para testar roles de forma completa. Com a integração dessas ferramentas em pipelines CI/CD, é possível automatizar a validação e manter a consistência dos playbooks.
Na próxima seção, vamos explorar a execução de playbooks com parâmetros avançados, como -i para inventário e --check para testes em modo de simulação, ajudando a otimizar a administração de playbooks em diferentes cenários.
13. Execução de Playbooks e Parâmetros Comuns
Objetivo
Explicar como executar playbooks com parâmetros comuns e opções avançadas, como inventários personalizados, execução simulada (--check) e níveis de verbosidade. Isso ajuda a otimizar a administração de playbooks em diferentes cenários e ambientes.
Conteúdo
Execução Básica de Playbooks com
ansible-playbookO comando
ansible-playbooké utilizado para executar playbooks no Ansible. Sua sintaxe básica requer apenas o caminho do playbook a ser executado, mas ele possui uma série de parâmetros úteis para customizar a execução.Exemplo de Execução Básica:
1
ansible-playbook playbook.yml
Especificando Inventários com
-iO parâmetro
-ipermite especificar um inventário customizado para a execução. É útil quando você possui múltiplos ambientes ou diferentes grupos de hosts.Exemplo: Usando um Inventário Personalizado:
1
ansible-playbook playbook.yml -i inventarios/producao- Explicação: Define o inventário
inventarios/producaopara a execução, aplicando o playbook aos hosts especificados nesse arquivo.
- Explicação: Define o inventário
Execução com Usuários e Sudo (
-ue-b)Os parâmetros
-ue-bsão usados para definir o usuário remoto e habilitar sudo, respectivamente.Exemplo: Executar com um Usuário Específico e Privilégios Elevados:
1
ansible-playbook playbook.yml -u deploy -b
- Explicação: Executa o playbook com o usuário
deploye eleva os privilégios comsudo.
- Explicação: Executa o playbook com o usuário
Modo de Simulação com
--checkO parâmetro
--checkexecuta o playbook em modo de simulação, mostrando o que seria alterado sem fazer modificações. Esse modo é útil para testar a execução e verificar o impacto das mudanças.Exemplo de Execução em Modo de Simulação:
1
ansible-playbook playbook.yml --check- Explicação: Exibe as alterações que o playbook faria sem aplicá-las de fato, permitindo uma pré-visualização.
Testando o Playbook com
--syntax-checkO parâmetro
--syntax-checkverifica a sintaxe do playbook, identificando erros de estrutura ou formatação.Exemplo: Verificar a Sintaxe de um Playbook:
1
ansible-playbook playbook.yml --syntax-check- Explicação: Realiza uma verificação de sintaxe para garantir que o playbook está corretamente estruturado antes da execução.
Listando Hosts e Tarefas com
--list-hostse--list-tasks--list-hosts: Exibe a lista de hosts onde o playbook será aplicado, sem executar as tarefas.--list-tasks: Exibe a lista de tarefas que serão executadas, proporcionando uma visão geral do que o playbook fará.
Exemplo de Uso:
1 2
ansible-playbook playbook.yml --list-hosts ansible-playbook playbook.yml --list-tasks
Modos Verbosos com
-v,-vv,-vvv,-vvvvA opção
-vaumenta a verbosidade, exibindo mais detalhes da execução. Com múltiplosv(de um a quatro), você pode controlar o nível de detalhe, sendo-vvvvo nível máximo, útil para diagnóstico completo.Exemplo de Execução com Verbosidade Máxima:
1
ansible-playbook playbook.yml -vvvv- Explicação: Exibe detalhes completos da execução, incluindo mensagens de depuração e comunicações com os hosts.
Forçando Atualizações com
--diffO parâmetro
--diffmostra as mudanças específicas em arquivos de configuração, indicando exatamente quais linhas foram adicionadas, removidas ou alteradas. É especialmente útil para tarefas que envolvem templates ou alterações de arquivos.Exemplo: Visualizar Diferenças em Arquivos:
1
ansible-playbook playbook.yml --diff- Explicação: Exibe as diferenças antes de aplicar as mudanças, útil para verificar edições em arquivos de configuração.
Exemplo Completo de Execução com Parâmetros Avançados
O exemplo abaixo utiliza vários parâmetros para uma execução completa, que inclui inventário personalizado, usuário específico, sudo, verbosidade, simulação e controle de mudanças.
1
ansible-playbook playbook.yml -i inventarios/producao -u deploy -b --check -vv --diff
- Explicação:
-i inventarios/producao: Usa o inventário de produção.-u deploy -b: Executa com o usuáriodeploye ativa sudo.--check: Simula a execução sem aplicar mudanças.-vv: Define o nível de verbosidade.--diff: Mostra as diferenças que seriam aplicadas aos arquivos.
- Explicação:
Tabela de Referência para Parâmetros Comuns do
ansible-playbook
| Parâmetro | Função | Exemplo |
|---|---|---|
-i | Define o inventário personalizado | -i inventarios/producao |
-u | Define o usuário remoto | -u deploy |
-b | Habilita sudo para execução com privilégios elevados | -b |
--check | Executa em modo de simulação | --check |
--syntax-check | Verifica a sintaxe do playbook | --syntax-check |
--list-hosts | Lista os hosts de execução sem executar | --list-hosts |
--list-tasks | Lista as tarefas do playbook sem executar | --list-tasks |
-v, -vv, -vvv, -vvvv | Define o nível de verbosidade | -vv |
--diff | Exibe as mudanças de arquivos | --diff |
Resumo
Com esses parâmetros, você pode executar playbooks de forma flexível e adaptada a diferentes cenários, desde execução simulada para validação de mudanças até análise detalhada de execução com níveis de verbosidade. Isso permite maior controle e visibilidade sobre a administração de sistemas, otimizando o uso de playbooks em ambientes variados.
Na próxima seção, vamos explorar boas práticas para organização e manutenção de playbooks, proporcionando uma estrutura mais eficiente e fácil de gerenciar para operações em ambientes complexos.
14. Boas Práticas para Organização e Manutenção de Playbooks
Objetivo
Fornecer um conjunto de boas práticas para organizar e manter playbooks Ansible, visando facilitar a administração, segurança e reutilização de configurações em ambientes complexos.
Conteúdo
Estrutura de Diretórios para Playbooks
Manter uma estrutura de diretórios organizada facilita a navegação e o entendimento do projeto. Em ambientes com múltiplos playbooks, roles e inventários, uma estrutura bem definida é essencial.
Exemplo de Estrutura de Diretórios:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
├── playbooks/ │ ├── site.yml # Playbook principal │ ├── webservers.yml # Playbook específico para servidores web │ ├── dbservers.yml # Playbook para servidores de banco de dados ├── inventories/ │ ├── production/ │ │ ├── hosts # Inventário de produção │ │ └── group_vars/ # Variáveis por grupo de produção │ └── staging/ │ ├── hosts # Inventário de staging │ └── group_vars/ # Variáveis por grupo de staging ├── roles/ │ ├── apache/ # Role para configurar Apache │ └── mysql/ # Role para configurar MySQL ├── group_vars/ │ └── all.yml # Variáveis comuns a todos os grupos ├── host_vars/ │ └── db1.yml # Variáveis específicas do host db1 └── files/ # Arquivos estáticos (ex.: templates, configs)
- Explicação: Cada componente tem seu próprio diretório (
playbooks,inventories,roles), facilitando o gerenciamento e a escalabilidade do projeto.
- Explicação: Cada componente tem seu próprio diretório (
Documentação de Playbooks e Tarefas
Cada playbook deve ter uma documentação clara, incluindo comentários que descrevam o propósito de cada play e tarefa. Isso é importante para facilitar o entendimento e a manutenção, especialmente em equipes.
Exemplo de Comentários no Playbook:
1 2 3 4 5 6 7 8 9 10 11
--- - name: Configuração de Servidor Web hosts: webservers become: yes tasks: - name: Instalar o Apache apt: name: apache2 state: present # Este handler será chamado se o Apache precisar ser reiniciado. notify: Reiniciar Apache
Nomeação Descritiva de Variáveis e Tarefas
Nomes descritivos para variáveis e tarefas ajudam a identificar facilmente o objetivo de cada ação no playbook, reduzindo a chance de erro e melhorando a legibilidade.
Exemplo de Variáveis com Nome Descritivo:
1 2 3
vars: apache_package_name: apache2 apache_config_file: /etc/apache2/apache2.conf
Uso de Roles para Reutilização e Modularidade
Sempre que possível, modularize funcionalidades em roles. Isso permite a reutilização de configurações e tarefas, além de facilitar a aplicação de configurações semelhantes em diferentes ambientes e playbooks.
Exemplo de Inclusão de Role em um Playbook:
1 2 3 4 5 6 7
--- - name: Configuração Completa do Servidor hosts: all become: yes roles: - apache - mysql
Isolamento de Variáveis Sensíveis com
Ansible VaultArmazene variáveis sensíveis, como senhas e chaves API, em arquivos criptografados com
Ansible Vault. Evite incluir informações confidenciais diretamente em arquivos de inventário ou playbooks.Exemplo de Configuração com
vars_filesCriptografado:1 2
vars_files: - vault.yml
Validação Regular com
ansible-lintemoleculeIntegrar
ansible-lintemoleculeao processo de desenvolvimento ajuda a garantir que os playbooks estão em conformidade com as boas práticas e que as roles são testadas em ambientes controlados antes da execução em produção.Automação de Execuções com Pipelines CI/CD
Configurar um pipeline de CI/CD permite executar playbooks automaticamente em ambientes de teste ou produção, além de aplicar verificações automáticas de sintaxe, segurança e testes funcionais.
Exemplo de Pipeline Básico com
ansible-lintemolecule:1 2 3 4 5 6 7 8 9 10 11
stages: - lint - test lint: script: - ansible-lint playbook.yml test: script: - molecule test
Exemplo Completo de Playbook com Boas Práticas
O exemplo abaixo segue algumas das boas práticas abordadas, com estrutura organizada, nomes descritivos, documentação e modularização em roles.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
--- - name: Configuração Completa de Servidor Web hosts: webservers become: yes vars_files: - vault.yml # Arquivo criptografado com variáveis sensíveis roles: - apache - firewall tasks: - name: Exibir a configuração atual do Apache debug: msg: "Apache configurado no servidor {{ ansible_hostname }}"
Checklist de Boas Práticas para Manutenção de Playbooks
- Estrutura de Diretórios: Separar playbooks, inventários e roles em diretórios específicos.
- Documentação: Adicionar descrições em todos os playbooks, plays e tarefas.
- Nomeação Descritiva: Nomear variáveis, playbooks e tarefas de forma clara e direta.
- Uso de Roles: Modularizar configurações em roles reutilizáveis.
- Segurança: Usar
Ansible Vaultpara variáveis sensíveis. - Validação Contínua: Integrar
ansible-lintemoleculeao fluxo de desenvolvimento. - Automação: Configurar pipelines CI/CD para deploy e validação automática de playbooks.
Resumo
Seguir boas práticas na organização e manutenção de playbooks Ansible torna os projetos mais seguros, modulares e fáceis de entender e atualizar. Com uma estrutura organizada, documentação adequada e integração com ferramentas de teste e CI/CD, os playbooks podem ser gerenciados de maneira eficiente e escalável em ambientes de produção complexos.
Na próxima seção, vamos concluir o tutorial com uma visão geral dos tópicos abordados e recomendações finais para o uso do Ansible em projetos de automação e gerenciamento de configurações.
Conclusão
Neste tutorial, exploramos uma ampla gama de funcionalidades e boas práticas para o uso de playbooks no Ansible, desde a criação de tarefas básicas até configurações avançadas de segurança, modularização e testes. Vamos resumir os principais pontos abordados e destacar as recomendações para otimizar o uso do Ansible em projetos de automação.
Resumo dos Tópicos Principais
- Introdução aos Playbooks:
- Compreendemos o conceito de playbooks como uma maneira de definir tarefas de automação em YAML, com organização e controle em vários níveis.
- Estrutura e Sintaxe:
- Detalhamos os principais elementos de um playbook, incluindo
hosts,tasks,vars,handlerse a estrutura básica para definir fluxos de execução.
- Detalhamos os principais elementos de um playbook, incluindo
- Controle Avançado de Tarefas:
- Vimos como utilizar
whenpara execução condicional,blockpara agrupar tarefas erescuepara tratamento de erros, aumentando a robustez dos playbooks.
- Vimos como utilizar
- Modularização com
include_tasks,import_taskse Roles:- Exploramos maneiras de modularizar e reutilizar tarefas, criando uma estrutura mais organizada e facilitando o gerenciamento de configurações complexas em ambientes variados.
- Segurança e Armazenamento de Variáveis Sensíveis:
- O
Ansible Vaultse mostrou fundamental para proteger informações críticas, enquanto práticas como isolamento de chaves SSH e o uso de variáveis de ambiente aumentaram a segurança dos dados sensíveis.
- O
- Ferramentas de Debugging e Testes:
- Ferramentas como
ansible-lintemoleculegarantem a qualidade dos playbooks, permitindo identificar problemas antes da execução em produção.
- Ferramentas como
- Execução de Playbooks e Parâmetros Avançados:
- A execução de playbooks com parâmetros avançados, como
--checkpara simulação e--diffpara verificação de mudanças, permite um controle maior sobre o comportamento e impacto das execuções.
- A execução de playbooks com parâmetros avançados, como
- Boas Práticas para Manutenção e Estruturação:
- Discutimos uma série de boas práticas para garantir que os playbooks sejam modulares, seguros e fáceis de entender e manter, facilitando o trabalho em equipe e o escalonamento das configurações.
Recomendações Finais
- Organize e Modularize:
- Estruturar playbooks em arquivos bem organizados, roles e módulos reutilizáveis é essencial para a escalabilidade e manutenção dos projetos.
- Use o
Ansible Vaultpara Segurança:- Proteger variáveis sensíveis deve ser uma prioridade, especialmente em ambientes de produção.
- Valide e Teste Regularmente:
- Integrar ferramentas de validação e teste contínuo, como
ansible-lintemolecule, ao fluxo de trabalho ajuda a evitar erros e mantém a qualidade dos playbooks.
- Integrar ferramentas de validação e teste contínuo, como
- Documente Cada Etapa:
- Documentar o propósito de cada tarefa, variáveis e roles garante que os playbooks sejam claros para todos os membros da equipe, facilitando colaborações e futuras revisões.
- Automatize com CI/CD:
- Um pipeline de CI/CD permite que alterações em playbooks sejam testadas automaticamente antes de serem aplicadas em produção, garantindo consistência e segurança em cada mudança.
Este guia completo sobre o uso de playbooks no Ansible oferece uma base sólida para criar, organizar e manter automações robustas e escaláveis em ambientes complexos. A adoção dessas práticas não só melhora a eficiência e a segurança, mas também contribui para uma infraestrutura mais resiliente e preparada para atender às demandas da equipe e dos sistemas que a sustentam.
Com essa compreensão, você está preparado para aproveitar o poder dos playbooks do Ansible e aplicá-los em seus projetos de automação e gestão de configurações. Boa sorte, e que seus playbooks sejam sempre executados com sucesso!