Post

Guia Completo de Ansible: Automação, Configuração e Boas Práticas

Um tutorial detalhado sobre Ansible, desde a instalação até práticas avançadas de automação e integração com CI/CD para gerenciar ambientes de desenvolvimento e produção.

Guia Completo de Ansible: Automação, Configuração e Boas Práticas

Tabela de Conteúdos

  1. Introdução ao Ansible e à Automação de Infraestrutura
  2. Instalação e Configuração do Ansible
  3. Configuração de Inventário no Ansible
  4. Introdução aos Playbooks do Ansible
  5. Uso de Módulos no Ansible para Tarefas Comuns
  6. Variáveis e Filtros no Ansible
  7. Loops e Condicionais em Playbooks
  8. Handlers e Notificações no Ansible
  9. Roles: Estrutura Modular para Playbooks
  10. Gerenciamento de Secrets e Vault do Ansible
  11. Debugging e Testes de Playbooks
  12. Implementação de Pipelines CI/CD com Ansible
  13. Configuração de Infraestrutura com Ansible e Cloud Providers
  14. Monitoramento e Log de Execuções do Ansible
  15. Práticas Recomendadas e Boas Práticas com Ansible

Seção 1: Introdução ao Ansible e à Automação de Infraestrutura

Objetivo:

Esta seção visa introduzir o Ansible e seu papel na automação de infraestrutura, destacando os conceitos fundamentais, principais componentes e diferenças entre o Ansible e outras ferramentas de automação, como Puppet e Chef.

1.1 O que é o Ansible?

O Ansible é uma ferramenta de automação de infraestrutura que permite gerenciar e configurar servidores, redes e aplicações de maneira simplificada, sem a necessidade de agentes instalados em cada máquina. Utilizando linguagem declarativa baseada em YAML, o Ansible facilita a configuração, provisionamento e orquestração de infraestrutura, sendo uma escolha comum para operações de TI e DevOps.

1.2 Benefícios do Ansible

  • Sem Agentes: Ansible opera via SSH, eliminando a necessidade de instalar softwares adicionais em hosts.
  • Fácil de Aprender: Baseado em YAML, o Ansible é acessível mesmo para profissionais com pouca experiência em programação.
  • Idempotência: Permite a execução repetida de tarefas sem alterar o estado se ele já estiver conforme esperado, reduzindo riscos de erro.
  • Amplo Suporte: Compatível com diversas plataformas, incluindo Linux, macOS e Windows.

1.3 Diferença entre Ansible e Outras Ferramentas de Automação (Puppet, Chef)

Aspecto Ansible Puppet Chef
Comunicação SSH (sem agentes) Agente/servidor Agente/servidor
Configuração Declarativa (YAML) Declarativa (DSL Puppet) Imperativa (Ruby)
Facilidade de Uso Alta Moderada Baixa para iniciantes
Compatibilidade Linux, Windows, macOS Principalmente Linux Principalmente Linux
Arquitetura Gerenciamento simplificado Infraestrutura mais complexa Escalabilidade maior, mas mais complexo

1.4 Principais Componentes do Ansible

Inventories

O inventário é uma lista de hosts que o Ansible gerencia. Ele pode ser um simples arquivo de texto (hosts) ou um script dinâmico que busca servidores de um serviço de nuvem. Com inventários, você pode organizar seus hosts em grupos e aplicar configurações a grupos específicos de servidores.

Playbooks

Os playbooks são arquivos YAML que definem as tarefas (plays) a serem executadas em hosts do inventário. Eles descrevem o estado desejado da infraestrutura e contêm tarefas organizadas em uma sequência lógica, como instalação de pacotes, configuração de serviços e execução de scripts.

Modules

Os módulos são componentes reutilizáveis que realizam tarefas específicas, como manipulação de arquivos, instalação de pacotes ou gerenciamento de usuários. Alguns dos módulos mais usados incluem apt, yum, file, service, entre outros.

Roles

Roles são uma forma de organizar e modularizar playbooks em estruturas reutilizáveis. Elas permitem que você divida um playbook complexo em componentes independentes e organizados, facilitando o gerenciamento e a reutilização de configurações.

Exemplo Resumido de um Playbook Simples: Aqui está um exemplo de playbook básico para entender sua estrutura. Este playbook instala o Apache em um servidor Linux.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- name: Instalação do Apache em um servidor
  hosts: webservers
  become: yes

  tasks:
    - name: Atualizar repositórios
      apt:
        update_cache: yes

    - name: Instalar Apache
      apt:
        name: apache2
        state: present

    - name: Iniciar e habilitar Apache
      service:
        name: apache2
        state: started
        enabled: yes

Resumo da Seção 1

Nessa introdução, você aprendeu:

  • O que é o Ansible e por que ele é uma escolha popular para automação de infraestrutura.
  • A diferença entre o Ansible e outras ferramentas, como Puppet e Chef.
  • Principais componentes do Ansible (inventories, playbooks, modules, roles) e seus papéis na estrutura da automação.

Seção 2: Instalação e Configuração do Ansible

Objetivo:

Esta seção visa mostrar o passo a passo para instalar o Ansible em diferentes sistemas operacionais e configurar a comunicação SSH entre o controlador (máquina onde o Ansible está instalado) e os hosts gerenciados. Verificaremos a instalação e exploraremos comandos básicos para garantir que tudo está funcionando corretamente.

2.1 Instalação do Ansible

2.1.1 Instalação em Linux

Em distribuições baseadas em Debian/Ubuntu, o Ansible pode ser instalado diretamente via APT.

  1. Atualize o sistema:
    1
    2
    
    sudo apt update
    sudo apt upgrade
    
  2. Instale o Ansible:
    1
    
    sudo apt install ansible -y
    

Para distribuições baseadas em Red Hat/CentOS, use o comando yum:

  1. Habilite o repositório EPEL (Extra Packages for Enterprise Linux):
    1
    
    sudo yum install epel-release -y
    
  2. Instale o Ansible:
    1
    
    sudo yum install ansible -y
    

2.1.2 Instalação em macOS

No macOS, o Ansible pode ser instalado via Homebrew:

  1. Instale o Homebrew (caso não tenha):
    1
    
    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
    
  2. Instale o Ansible:
    1
    
    brew install ansible
    

2.1.3 Instalação no Windows

Para o Windows, a instalação do Ansible geralmente é feita através do Windows Subsystem for Linux (WSL). Seguem os passos:

  1. Instale o WSL (caso não tenha):
    • Execute o comando no PowerShell:
      1
      
      wsl --install
      
  2. Instale uma distribuição Linux (ex: Ubuntu) através da Microsoft Store.

  3. Instale o Ansible na distribuição Linux dentro do WSL:
    1
    2
    
    sudo apt update
    sudo apt install ansible -y
    

2.2 Configuração Básica de SSH para Comunicação com Hosts

O Ansible utiliza SSH para se conectar aos hosts gerenciados. Abaixo, veja como configurar a autenticação via chave SSH, que é uma prática recomendada para garantir segurança.

2.2.1 Geração de Chave SSH

  1. Crie um par de chaves SSH no controlador (máquina que executa o Ansible):
    1
    
    ssh-keygen -t rsa -b 4096
    

    Pressione Enter para aceitar o local padrão e (opcionalmente) defina uma senha para maior segurança.

  2. Copie a chave pública para o host remoto:
    1
    
    ssh-copy-id user@host_remoto
    

    Substitua user pelo nome do usuário no host e host_remoto pelo endereço IP ou hostname do host.

2.2.2 Verificando a Conexão SSH

Para garantir que a configuração SSH foi realizada corretamente, conecte-se ao host remoto usando SSH:

1
ssh user@host_remoto

Se tudo estiver correto, o acesso será realizado sem necessidade de senha (caso uma chave SSH tenha sido usada).

2.3 Verificação da Instalação do Ansible

Para verificar se o Ansible está corretamente instalado e configurado, use o comando:

1
ansible --version

Isso exibirá a versão do Ansible instalada e o caminho dos arquivos de configuração, incluindo o ansible.cfg e o diretório dos módulos.

2.4 Primeiro Comando Ansible: Ping

Para testar a conexão do Ansible com os hosts, execute um simples comando de ping. Primeiro, crie um arquivo de inventário básico chamado hosts no diretório atual, com o IP do host gerenciado:

Exemplo de Arquivo de Inventário (hosts):

1
2
[servidores_web]
192.168.1.10

Com o inventário pronto, execute o comando de ping:

1
ansible -i hosts servidores_web -m ping

Esse comando usa o módulo ping para verificar a conectividade com os hosts do grupo servidores_web no inventário hosts. A resposta esperada será:

1
2
3
4
192.168.1.10 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Essa resposta indica que a configuração está correta e o Ansible conseguiu se conectar ao host.

Resumo da Seção 2

Nessa seção, você aprendeu:

  • Como instalar o Ansible em Linux, macOS e Windows.
  • Configuração básica de SSH para comunicação segura entre o Ansible e os hosts.
  • Como verificar a instalação e testar a conectividade com hosts utilizando o comando ping.

Seção 3: Configuração de Inventário no Ansible

Objetivo:

Explicar a estrutura e sintaxe do inventário do Ansible e como definir hosts e grupos de máquinas, permitindo a aplicação de configurações específicas para diferentes conjuntos de servidores. Vamos também abordar o uso de inventários dinâmicos para ambientes de nuvem e variáveis de host para personalizar a configuração de cada máquina.

3.1 Estrutura e Sintaxe do Arquivo de Inventário (hosts)

O inventário do Ansible é um arquivo que lista os hosts (servidores) que serão gerenciados. Esse arquivo pode ser um simples arquivo de texto, onde definimos IPs ou nomes de hosts, ou uma fonte dinâmica, como scripts ou APIs, para buscar informações de infraestrutura em nuvem.

Por padrão, o Ansible utiliza o arquivo /etc/ansible/hosts, mas você pode criar arquivos de inventário personalizados e especificá-los usando a opção -i ao executar os comandos.

Exemplo de Arquivo de Inventário Básico (hosts):

1
2
3
4
5
6
7
[servidores_web]
192.168.1.10
192.168.1.11

[servidores_db]
db1.example.com
db2.example.com

Neste exemplo:

  • servidores_web e servidores_db são grupos de hosts, facilitando a aplicação de configurações específicas a cada grupo.
  • Cada grupo contém uma lista de IPs ou nomes DNS dos hosts.

Agrupando Grupos de Hosts (Grupos Aninhados)

É possível agrupar grupos de hosts para configurar um ambiente maior:

1
2
3
4
5
6
7
8
9
10
11
[frontend]
192.168.1.10
192.168.1.11

[backend]
192.168.1.12
192.168.1.13

[aplicacao:children]
frontend
backend

O grupo aplicacao agora engloba os grupos frontend e backend, permitindo a execução de configurações em todos esses hosts de uma só vez.

3.2 Uso de Variáveis em Inventários

O Ansible permite associar variáveis específicas aos hosts ou grupos diretamente no inventário, possibilitando configurações personalizadas.

Variáveis de Host

As variáveis de host podem ser definidas logo após o IP ou o nome do host, para ajustar o comportamento da configuração:

1
2
3
[servidores_web]
web1 ansible_host=192.168.1.10 ansible_user=admin ansible_port=2222
web2 ansible_host=192.168.1.11 ansible_user=admin ansible_port=2222

Neste exemplo:

  • ansible_host especifica o endereço IP do host, que pode ser diferente do nome do host.
  • ansible_user define o usuário SSH para conectar-se ao host.
  • ansible_port especifica uma porta SSH alternativa.

Variáveis de Grupo

Variáveis de grupo são aplicadas a todos os hosts em um grupo e são definidas em uma seção especial chamada [group:vars]:

1
2
3
4
5
6
7
[servidores_web]
web1 ansible_host=192.168.1.10
web2 ansible_host=192.168.1.11

[servidores_web:vars]
ansible_user=admin
ansible_port=2222

Aqui, todos os hosts do grupo servidores_web herdam as variáveis ansible_user e ansible_port, eliminando a necessidade de defini-las individualmente para cada host.

3.3 Inventários Dinâmicos

Inventários dinâmicos permitem que o Ansible obtenha informações de inventário em tempo real de fontes como Amazon AWS, Google Cloud, Microsoft Azure, etc. Para isso, você utiliza scripts ou plugins específicos de cada provedor de nuvem.

Exemplo de Uso com AWS

  1. Instale o Plugin AWS: Primeiro, instale o pacote boto3, que é a biblioteca de integração com AWS:

    1
    
    pip install boto3
    
  2. Configure as Credenciais AWS: Defina as credenciais em ~/.aws/credentials:

    1
    2
    3
    
    [default]
    aws_access_key_id = SUA_ACCESS_KEY
    aws_secret_access_key = SUA_SECRET_KEY
    
  3. Utilize o Plugin AWS para Inventário Dinâmico: Crie um arquivo aws_ec2.yaml com a configuração do inventário dinâmico:

    1
    2
    3
    4
    5
    6
    7
    8
    
    plugin: amazon.aws.aws_ec2
    regions:
      - us-east-1
    filters:
      tag:Environment: production
    keyed_groups:
      - key: tags.Name
        prefix: 'aws_'
    
  4. Executar o Comando Ansible com Inventário Dinâmico:

    1
    
    ansible-inventory -i aws_ec2.yaml --graph
    

    Esse comando mostra a estrutura do inventário baseado nas instâncias EC2 disponíveis com a tag Environment: production na região us-east-1.

3.4 Exemplo Prático de Inventário e Execução de Tarefas

Com um inventário configurado, podemos aplicar uma tarefa a um grupo específico. Veja como definir um inventário para aplicar uma configuração específica em servidores de um grupo.

Inventário de Exemplo:

1
2
3
4
5
6
7
[webservers]
192.168.1.10
192.168.1.11

[databases]
192.168.1.12
192.168.1.13

Playbook para Atualização de Pacotes em webservers

Crie um playbook atualiza_pacotes.yaml:

1
2
3
4
5
6
7
8
9
10
11
12
13
- name: Atualização de Pacotes nos Web Servers
  hosts: webservers
  become: yes
  tasks:
    - name: Atualizar Cache de Pacotes
      apt:
        update_cache: yes
      when: ansible_os_family == "Debian"

    - name: Atualizar Todos os Pacotes
      apt:
        upgrade: dist
      when: ansible_os_family == "Debian"

Neste playbook:

  • As tarefas são aplicadas aos hosts no grupo webservers.
  • Usamos a condição when para garantir que a atualização só seja feita em sistemas baseados em Debian (como Ubuntu).

Executando o Playbook

Para executar o playbook com o inventário definido, use o comando:

1
ansible-playbook -i hosts atualiza_pacotes.yaml

Resumo da Seção 3

Nessa seção, você aprendeu:

  • A estrutura e sintaxe do arquivo de inventário do Ansible, incluindo grupos e variáveis.
  • Como definir variáveis para hosts e grupos, personalizando configurações específicas.
  • A criar inventários dinâmicos, especialmente para integrações com nuvem, como AWS.
  • A executar um playbook que utiliza inventários para aplicar configurações a grupos específicos de servidores.

Seção 4: Introdução aos Playbooks do Ansible

Objetivo:

Apresentar a estrutura de um playbook e como utilizá-los para criar tarefas automatizadas no Ansible. Vamos explorar a sintaxe básica do YAML, entender os principais componentes de um playbook e ver um exemplo de automação simples.

4.1 O Que São Playbooks?

Playbooks são arquivos no formato YAML que definem conjuntos de instruções (tasks) para serem executadas em hosts do inventário. Eles descrevem o estado desejado da infraestrutura ou das aplicações e fornecem uma estrutura lógica para as automações. Em essência, playbooks são como “scripts” que o Ansible utiliza para configurar e gerenciar sistemas.

4.2 Estrutura de um Playbook

A estrutura de um playbook Ansible inclui os seguintes elementos principais:

  1. Hosts: Define em quais servidores ou grupos as tarefas serão executadas.
  2. Tasks: Listagem de tarefas, ou seja, ações que o Ansible deve executar em cada host.
  3. Handlers: Tarefas que são acionadas em resposta a mudanças (ex: reiniciar um serviço após uma configuração).
  4. Vars: Definição de variáveis que serão utilizadas nas tarefas, tornando os playbooks mais dinâmicos.

4.3 Sintaxe Básica do YAML para Playbooks

O Ansible usa o formato YAML, que é fácil de ler e escrever. Alguns pontos importantes do YAML:

  • A indentação deve ser consistente (normalmente 2 espaços).
  • Hifens (-) são usados para listas.
  • Os : (dois-pontos) são usados para definir pares de chave-valor.

4.4 Estrutura Básica de um Playbook

Abaixo está um exemplo simples de um playbook para instalar o Apache em servidores do grupo webservers:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- name: Instalação do Apache nos Web Servers
  hosts: webservers
  become: yes  # Eleva as permissões para executar comandos como root

  tasks:
    - name: Atualizar o Cache de Pacotes
      apt:
        update_cache: yes

    - name: Instalar o Apache
      apt:
        name: apache2
        state: present

    - name: Iniciar e Habilitar o Serviço Apache
      service:
        name: apache2
        state: started
        enabled: yes

Explicação do Playbook:

  • name: Nome descritivo para cada parte do playbook e cada tarefa, facilitando o entendimento e a leitura.
  • hosts: Define o grupo de hosts (no caso, webservers) onde o playbook será executado.
  • become: Define que as tarefas serão executadas com permissões elevadas (root).
  • tasks: Lista de tarefas a serem realizadas em cada host definido. Cada tarefa tem um name e um módulo do Ansible, como apt ou service.

4.5 Componentes Importantes dos Playbooks

Tasks

Cada task (tarefa) usa um módulo do Ansible para realizar uma ação, como instalar um pacote, gerenciar um serviço ou editar arquivos.

1
2
3
4
5
tasks:
  - name: Exemplo de Tarefa
    apt:
      name: apache2
      state: present

Handlers

Os handlers são tarefas que são executadas em resposta a uma mudança de estado. Por exemplo, se o Ansible instalar ou atualizar o Apache, ele pode acionar um handler para reiniciar o serviço.

1
2
3
4
5
handlers:
  - name: Reiniciar Apache
    service:
      name: apache2
      state: restarted

Para acionar um handler, adicione a opção notify em uma tarefa:

1
2
3
4
5
6
tasks:
  - name: Instalar o Apache
    apt:
      name: apache2
      state: latest
    notify: Reiniciar Apache

Variáveis (vars)

As variáveis (vars) permitem tornar os playbooks mais flexíveis e reutilizáveis. Elas podem ser definidas em diferentes partes de um playbook e podem ser usadas nas tarefas.

1
2
3
4
5
6
7
8
9
10
11
12
- name: Instalação do Apache nos Web Servers
  hosts: webservers
  become: yes

  vars:
    apache_package: apache2

  tasks:
    - name: Instalar o Apache
      apt:
        name: "{{ apache_package }}"
        state: present

Neste exemplo, apache_package é uma variável e seu valor será substituído nas tarefas.

4.6 Exemplo Prático: Configuração de um Servidor Web Completo

Vamos ver um playbook que instala o Apache, configura um arquivo de índice personalizado e reinicia o serviço se houver alguma mudança. O playbook usa variáveis, tasks e handlers.

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: Configuração Completa do Servidor Web
  hosts: webservers
  become: yes

  vars:
    apache_package: apache2
    apache_index: "/var/www/html/index.html"
    index_content: "<h1>Bem-vindo ao Servidor Web!</h1>"

  tasks:
    - name: Instalar Apache
      apt:
        name: "{{ apache_package }}"
        state: present

    - name: Criar Página Inicial Personalizada
      copy:
        content: "{{ index_content }}"
        dest: "{{ apache_index }}"
      notify: Reiniciar Apache

  handlers:
    - name: Reiniciar Apache
      service:
        name: apache2
        state: restarted

Explicação do Exemplo:

  • Vars: Definimos variáveis para o nome do pacote (apache_package), o caminho do arquivo de índice (apache_index) e o conteúdo da página (index_content).
  • Tasks:
    • A primeira tarefa instala o Apache.
    • A segunda tarefa usa o módulo copy para criar um arquivo de índice HTML com o conteúdo definido em index_content. Se houver alteração, ele notifica o handler para reiniciar o Apache.
  • Handlers: O handler Reiniciar Apache é executado somente se houver alteração na segunda tarefa.

4.7 Executando um Playbook

Para executar o playbook servidor_web.yaml no inventário hosts, usamos o comando:

1
ansible-playbook -i hosts servidor_web.yaml

Esse comando executará o playbook em todos os hosts do grupo webservers, conforme definido no arquivo hosts.

4.8 Estrutura do Playbook Completo com Explicações

Elemento Descrição
name Nome descritivo do playbook ou da tarefa, útil para identificar o que cada bloco executa.
hosts Define o grupo de hosts onde as tarefas serão executadas.
become Habilita permissões elevadas (sudo) para a execução das tarefas.
vars Define variáveis para serem usadas no playbook.
tasks Lista de tarefas a serem executadas nos hosts. Cada tarefa usa um módulo específico para realizar uma ação (ex: apt para instalar pacotes).
notify Indica que um handler será notificado para executar uma ação específica, caso uma tarefa tenha mudado o estado do sistema.
handlers Tarefas especiais que são executadas somente quando notificadas. São comumente usadas para reiniciar serviços após uma mudança de configuração.

Resumo da Seção 4

Nessa seção, você aprendeu:

  • A estrutura e os elementos básicos de um playbook no Ansible.
  • Como definir e organizar tarefas, variáveis e handlers.
  • Criar e executar um playbook prático que instala e configura um servidor web.

Seção 5: Uso de Módulos no Ansible para Tarefas Comuns

Objetivo:

Ensinar a utilizar módulos do Ansible para realizar tarefas de gerenciamento de sistemas, como instalação de pacotes, gerenciamento de serviços e manipulação de arquivos. Vamos ver alguns dos módulos mais comuns e exemplos práticos para aplicá-los em automações.

5.1 O Que São Módulos no Ansible?

Módulos são scripts pré-definidos no Ansible que realizam operações específicas em hosts gerenciados. Eles são invocados dentro das tarefas (tasks) em playbooks e fornecem uma interface simples para executar ações complexas. O Ansible vem com centenas de módulos para diferentes propósitos, como gerenciamento de sistemas, rede, nuvem, bancos de dados e muito mais.

5.2 Principais Módulos para Tarefas Comuns

Vamos explorar alguns dos módulos mais utilizados para tarefas do dia-a-dia na administração de sistemas:

Módulo Função
apt Gerenciamento de pacotes em sistemas Debian/Ubuntu.
yum Gerenciamento de pacotes em sistemas RHEL/CentOS.
file Manipulação de permissões e propriedades de arquivos.
copy Cópia de arquivos ou conteúdo para hosts remotos.
template Geração de arquivos a partir de templates Jinja2.
service Controle de serviços (iniciar, parar, reiniciar).
user Gerenciamento de usuários e grupos.
command Execução de comandos no host remoto (sem interpretação de shell).
shell Execução de comandos no shell do host remoto.

5.3 Exemplos Práticos com Módulos

5.3.1 Módulo apt - Gerenciamento de Pacotes (Debian/Ubuntu)

O módulo apt é utilizado para instalar, remover e atualizar pacotes em sistemas baseados em Debian/Ubuntu.

1
2
3
4
5
- name: Instalar o Apache em Debian/Ubuntu
  apt:
    name: apache2
    state: present
    update_cache: yes

Neste exemplo:

  • name: Nome do pacote a ser gerenciado (apache2).
  • state: Define que o pacote deve estar presente (present), ou seja, instalado.
  • update_cache: Atualiza a lista de pacotes antes de instalar.

5.3.2 Módulo yum - Gerenciamento de Pacotes (RHEL/CentOS)

Para sistemas baseados em Red Hat/CentOS, o módulo yum funciona de forma semelhante ao apt.

1
2
3
4
- name: Instalar o Apache em RHEL/CentOS
  yum:
    name: httpd
    state: present

5.3.3 Módulo file - Manipulação de Arquivos e Diretórios

O módulo file permite gerenciar arquivos e diretórios, incluindo permissões, proprietário e grupo.

1
2
3
4
5
6
7
- name: Criar diretório para logs
  file:
    path: /var/log/meu_app
    state: directory
    mode: '0755'
    owner: www-data
    group: www-data

Neste exemplo:

  • path: Caminho do diretório ou arquivo.
  • state: Define que o item deve ser um diretório (directory).
  • mode, owner, group: Permissões e proprietário.

5.3.4 Módulo copy - Cópia de Arquivos

O módulo copy permite copiar arquivos ou conteúdo para os hosts remotos.

1
2
3
4
5
- name: Copiar uma página de boas-vindas personalizada
  copy:
    content: "<h1>Bem-vindo ao meu servidor!</h1>"
    dest: /var/www/html/index.html
    mode: '0644'

Aqui, estamos copiando o conteúdo HTML diretamente para o arquivo /var/www/html/index.html.

5.3.5 Módulo template - Criação de Arquivos a partir de Templates

O módulo template é semelhante ao copy, mas utiliza templates Jinja2, que permitem o uso de variáveis.

Exemplo de Template (index.html.j2):

1
2
3
4
5
6
7
8
9
<!DOCTYPE html>
<html>
  <head>
    <title>{{ site_name }}</title>
  </head>
  <body>
    <h1>Bem-vindo ao {{ site_name }}!</h1>
  </body>
</html>

Playbook usando o Template:

1
2
3
4
5
6
7
- name: Criar página de boas-vindas com template
  template:
    src: templates/index.html.j2
    dest: /var/www/html/index.html
    mode: '0644'
  vars:
    site_name: "Meu Site"

5.3.6 Módulo service - Gerenciamento de Serviços

O módulo service gerencia serviços no sistema, permitindo iniciar, parar, reiniciar e habilitar serviços para inicialização no boot.

1
2
3
4
5
- name: Iniciar e habilitar o serviço Apache
  service:
    name: apache2
    state: started
    enabled: yes

5.3.7 Módulo user - Gerenciamento de Usuários e Grupos

O módulo user é útil para criar e gerenciar usuários e grupos.

1
2
3
4
5
6
- name: Criar um novo usuário
  user:
    name: deploy
    state: present
    groups: sudo
    shell: /bin/bash

5.3.8 Módulo command e shell - Execução de Comandos

Os módulos command e shell permitem executar comandos em hosts remotos. A diferença é que command executa diretamente o comando, enquanto shell permite o uso de variáveis do shell.

Exemplo com command:

1
2
- name: Listar conteúdo do diretório
  command: ls -l /var/www

Exemplo com shell:

1
2
- name: Executar script com variáveis de ambiente
  shell: "echo $HOME"

5.4 Exemplo de Playbook com Vários Módulos

Vamos criar um playbook que instala o Apache, cria um diretório de logs, copia uma página de boas-vindas personalizada e configura permissões para o diretório de logs.

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
- name: Configuração Completa do Servidor Web
  hosts: webservers
  become: yes

  vars:
    apache_package: apache2
    log_directory: /var/log/meu_app
    welcome_page_content: "<h1>Bem-vindo ao servidor!</h1>"

  tasks:
    - name: Instalar Apache
      apt:
        name: "{{ apache_package }}"
        state: present
        update_cache: yes

    - name: Criar diretório de logs
      file:
        path: "{{ log_directory }}"
        state: directory
        mode: '0755'
        owner: www-data
        group: www-data

    - name: Copiar página de boas-vindas
      copy:
        content: "{{ welcome_page_content }}"
        dest: /var/www/html/index.html
        mode: '0644'

    - name: Iniciar e habilitar o Apache
      service:
        name: "{{ apache_package }}"
        state: started
        enabled: yes

Neste playbook:

  • Usamos o módulo apt para instalar o Apache.
  • O módulo file cria um diretório de logs com permissões específicas.
  • O módulo copy cria uma página HTML personalizada.
  • O módulo service inicia e habilita o Apache.

Resumo da Seção 5

Nessa seção, você aprendeu:

  • O que são módulos no Ansible e como eles facilitam tarefas de automação.
  • Exemplos práticos de uso dos principais módulos (apt, yum, file, copy, template, service, user, command, shell).
  • A criar um playbook que utiliza múltiplos módulos para configurar um servidor web.

Seção 6: Variáveis e Filtros no Ansible

Objetivo:

Explicar o uso de variáveis no Ansible para tornar playbooks flexíveis e reutilizáveis, além de ensinar o uso de filtros Jinja2 para manipular dados dentro dos playbooks.

6.1 O Que São Variáveis no Ansible?

As variáveis no Ansible permitem armazenar valores reutilizáveis que podem ser usados em várias partes do playbook, facilitando a personalização das configurações. Com variáveis, você pode definir valores específicos para hosts ou grupos e alterar configurações rapidamente sem modificar o playbook inteiro.

As variáveis são definidas de várias maneiras no Ansible:

  • Diretamente nos playbooks (com a chave vars)
  • Em arquivos de variáveis (group_vars e host_vars)
  • Em inventários
  • Passadas via linha de comando

6.2 Definição de Variáveis em Playbooks

As variáveis podem ser definidas diretamente nos playbooks usando a chave vars. Veja um exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- name: Configuração do Servidor Web
  hosts: webservers
  become: yes

  vars:
    apache_package: apache2
    welcome_message: "Bem-vindo ao meu servidor!"

  tasks:
    - name: Instalar Apache
      apt:
        name: "{{ apache_package }}"
        state: present
        update_cache: yes

    - name: Criar Página de Boas-Vindas
      copy:
        content: "{{ welcome_message }}"
        dest: /var/www/html/index.html

Aqui:

  • apache_package e welcome_message são variáveis que armazenam valores reutilizáveis.
  • Essas variáveis são referenciadas com {{ }} (chaves duplas) e substituídas pelos valores durante a execução.

6.3 Utilizando Arquivos de Variáveis (group_vars e host_vars)

Os arquivos de variáveis permitem definir valores específicos para grupos de hosts ou hosts individuais fora do playbook, o que facilita o gerenciamento de ambientes mais complexos.

  • Group Vars: Variáveis específicas para um grupo de hosts, localizadas na pasta group_vars.
  • Host Vars: Variáveis específicas para um único host, localizadas na pasta host_vars.

Exemplo de Estrutura de Diretórios:

1
2
3
4
5
6
inventory/
├── hosts
├── group_vars/
│   └── webservers.yaml
└── host_vars/
    └── web1.yaml

Arquivo de Variáveis de Grupo (group_vars/webservers.yaml):

1
2
apache_package: apache2
welcome_message: "Bem-vindo ao cluster de webservers!"

Arquivo de Variáveis de Host (host_vars/web1.yaml):

1
welcome_message: "Bem-vindo ao webserver específico: web1"

Essa estrutura permite configurar mensagens ou pacotes personalizados para cada grupo ou host individualmente.

6.4 Sobrescrita e Hierarquia de Variáveis

Quando o Ansible encontra variáveis definidas em diferentes lugares, ele segue uma hierarquia de precedência. A ordem simplificada de precedência é:

  1. Variáveis de linha de comando (maior precedência).
  2. Variáveis definidas no playbook (vars).
  3. Arquivos de variáveis (group_vars, host_vars).
  4. Variáveis definidas em inventários.

Essa ordem permite que você sobrescreva configurações conforme necessário.

6.5 Filtros no Ansible

Filtros permitem manipular dados nas variáveis, utilizando a sintaxe Jinja2. Alguns filtros úteis incluem:

  • default: Define um valor padrão se a variável não estiver definida.
  • upper, lower: Converte strings para letras maiúsculas ou minúsculas.
  • replace: Substitui uma parte da string.
  • length: Retorna o tamanho de uma lista ou string.

Exemplo de Uso de Filtros

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- name: Configuração com Filtros
  hosts: webservers
  become: yes

  vars:
    user_name: "admin"
    server_message: "Bem-vindo ao Servidor"

  tasks:
    - name: Exibir Nome de Usuário em Maiúsculas
      debug:
        msg: "{{ user_name | upper }}"

    - name: Mensagem de Servidor com Valor Padrão
      debug:
        msg: "{{ server_message | default('Servidor em Manutenção') }}"

Aqui:

  • O filtro upper transforma user_name para maiúsculas.
  • O filtro default define um valor padrão para server_message caso a variável não tenha um valor.

6.6 Filtros em Listas e Dicionários

Jinja2 oferece filtros avançados para manipulação de listas e dicionários, úteis para manipular dados complexos. Veja alguns exemplos:

Exemplo de Manipulação de Listas

1
2
3
4
5
6
7
8
9
10
- name: Manipulação de Listas
  hosts: localhost

  vars:
    users: ["alice", "bob", "carol"]

  tasks:
    - name: Exibir Lista de Usuários em Ordem Alfabética
      debug:
        msg: "{{ users | sort }}"

Exemplo de Manipulação de Dicionários

1
2
3
4
5
6
7
8
9
10
11
12
13
- name: Manipulação de Dicionários
  hosts: localhost

  vars:
    app_config:
      app_name: "MinhaApp"
      version: "1.2"
      env: "production"

  tasks:
    - name: Exibir Nome da Aplicação
      debug:
        msg: "{{ app_config['app_name'] }}{ endraw %}"

6.7 Exemplo Prático: Playbook Usando Variáveis e Filtros

Vamos criar um playbook que configura um servidor web e personaliza uma página HTML com variáveis e filtros.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- name: Configuração do Servidor Web com Variáveis e Filtros
  hosts: webservers
  become: yes

  vars:
    apache_package: apache2
    welcome_message: "Bem-vindo ao {% raw %}{{ environment | default('desenvolvimento') }}"
    environment: "produção"

  tasks:
    - name: Instalar Apache
      apt:
        name: "{{ apache_package }}"
        state: present
        update_cache: yes

    - name: Criar Página Personalizada
      copy:
        content: "{{ welcome_message | upper }}"
        dest: /var/www/html/index.html
        mode: '0644'

Neste exemplo:

  • welcome_message usa o filtro default para definir um valor padrão para environment se ele não estiver definido.
  • O filtro upper é aplicado à mensagem final para exibir o texto em letras maiúsculas.

Resumo da Seção 6

Nessa seção, você aprendeu:

  • Como definir e utilizar variáveis no Ansible, tanto em playbooks quanto em arquivos de variáveis.
  • A hierarquia de precedência das variáveis e como utilizá-las para configurar diferentes ambientes.
  • Como utilizar filtros Jinja2 para manipulação de dados nas variáveis.
  • Exemplos práticos de playbooks com variáveis e filtros para personalizar configurações.

Seção 7: Loops e Condicionais em Playbooks

Objetivo:

Ensinar a criar playbooks com loops e condicionais, permitindo a aplicação de tarefas em listas e a execução de tarefas somente em condições específicas. Esses recursos aumentam a capacidade de automação do Ansible, adaptando-se a diferentes cenários.

7.1 Loops em Playbooks

Loops permitem que você repita uma tarefa várias vezes para uma lista de itens. Com loops, é possível aplicar uma tarefa a vários hosts, pacotes, arquivos, usuários, e outros itens sem precisar repetir o código manualmente.

7.1.1 Usando loop com with_items

O loop mais básico no Ansible é o loop, que substitui o método anterior with_items. Veja um exemplo para instalar uma lista de pacotes:

1
2
3
4
5
6
7
8
- name: Instalar Pacotes Necessários
  apt:
    name: "{{ item }}"
    state: present
  loop:
    - apache2
    - vim
    - curl

Neste exemplo:

  • A tarefa será executada para cada item na lista, instalando apache2, vim e curl.

7.1.2 Loop com Dicionários (usando loop e with_dict)

Para loops mais complexos, o Ansible permite iterar sobre dicionários. Vamos criar um exemplo onde configuramos usuários com base em um dicionário que contém o nome do usuário e o shell:

1
2
3
4
5
6
7
8
- name: Criar Usuários com Shells Específicos
  user:
    name: "{{ item.key }}"
    shell: "{{ item.value.shell }}"
    state: present
  loop:
    - { key: "alice", value: { shell: "/bin/bash" } }
    - { key: "bob", value: { shell: "/bin/zsh" } }

Nesse caso:

  • item.key e item.value.shell acessam as chaves e valores de cada dicionário.

7.1.3 Loop com Índices

Se precisar de um índice, use ansible_loop.index para gerar uma contagem durante o loop. Veja um exemplo:

1
2
3
4
5
6
7
8
- name: Criar Arquivos de Configuração com Índices
  copy:
    content: "Conteúdo do arquivo {{ ansible_loop.index }}"
    dest: "/tmp/arquivo_{{ ansible_loop.index }}.txt"
  loop:
    - 1
    - 2
    - 3

Aqui:

  • ansible_loop.index permite numerar cada arquivo durante a execução do loop.

7.2 Condicionais em Playbooks

Condicionais permitem controlar a execução de uma tarefa com base em uma condição. As condições são configuradas com o parâmetro when, que avalia uma expressão antes de decidir se a tarefa será executada.

7.2.1 Condicionais Simples

Um exemplo de condição básica é executar uma tarefa baseada no sistema operacional:

1
2
3
4
5
- name: Instalar Apache em Sistemas Debian/Ubuntu
  apt:
    name: apache2
    state: present
  when: ansible_os_family == "Debian"

Nesse caso:

  • A tarefa será executada apenas se ansible_os_family for Debian.

7.2.2 Condicionais com Variáveis

Você pode usar variáveis para controlar a execução da tarefa. Vamos criar uma variável enable_apache que controla se o Apache será instalado:

1
2
3
4
5
- name: Instalar Apache Condicionalmente
  apt:
    name: apache2
    state: present
  when: enable_apache

Defina enable_apache: true no inventário ou arquivo de variáveis para que a tarefa seja executada. Caso contrário, ela será ignorada.

7.2.3 Condicionais Múltiplas

Você pode combinar condições usando and, or e not para controlar a execução:

1
2
3
4
5
- name: Instalar Pacotes em Sistema Debian e Ambiente de Produção
  apt:
    name: apache2
    state: present
  when: ansible_os_family == "Debian" and environment == "production"

7.3 Exemplo Prático: Playbook com Loops e Condicionais

Vamos criar um playbook que:

  • Instala pacotes básicos para o ambiente.
  • Cria usuários com base em uma lista.
  • Configura o firewall, mas somente em sistemas Debian/Ubuntu.
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
- name: Configuração do Servidor com Loops e Condicionais
  hosts: all
  become: yes

  vars:
    packages:
      - vim
      - curl
      - git
    users:
      - name: "alice"
        shell: "/bin/bash"
      - name: "bob"
        shell: "/bin/zsh"
    enable_firewall: true

  tasks:
    - name: Instalar Pacotes Básicos
      apt:
        name: "{{ item }}"
        state: present
      loop: "{{ packages }}"

    - name: Criar Usuários
      user:
        name: "{{ item.name }}"
        shell: "{{ item.shell }}"
        state: present
      loop: "{{ users }}"

    - name: Configurar Firewall (Apenas em Debian/Ubuntu)
      command: ufw allow 22
      when: ansible_os_family == "Debian" and enable_firewall

Explicação do Exemplo:

  • Loop de Pacotes: Instalamos pacotes básicos definidos em packages.
  • Loop de Usuários: Criamos usuários com shell específico.
  • Condicional para Firewall: Configuramos o firewall apenas em sistemas Debian/Ubuntu e se enable_firewall for verdadeiro.

Resumo da Seção 7

Nessa seção, você aprendeu:

  • Como usar loops no Ansible com loop e with_items para repetir tarefas em listas.
  • A manipular dicionários e índices em loops para cenários mais complexos.
  • A usar condicionais com o parâmetro when para controlar a execução das tarefas.
  • Exemplo prático de playbook com loops e condicionais para configuração de servidores.

Seção 8: Handlers e Notificações no Ansible

Objetivo:

Demonstrar como usar handlers para executar tarefas específicas em resposta a eventos, evitando execuções desnecessárias e permitindo um controle eficiente das ações dependentes.

8.1 O Que São Handlers?

Handlers no Ansible são tarefas especiais que são executadas somente quando notificadas por outra tarefa. Eles são ideais para ações que só precisam ocorrer se houver mudanças em uma configuração, como reiniciar um serviço após uma atualização de arquivo.

  • Evita Execuções Desnecessárias: Se uma tarefa não realizar mudanças, o handler não será executado.
  • Idempotência: Os handlers ajudam a garantir que uma operação seja realizada apenas quando necessário, respeitando o princípio de idempotência do Ansible.

8.2 Estrutura Básica de um Handler

Os handlers são definidos no mesmo nível das tasks, geralmente no final do playbook, usando a chave handlers. Cada handler tem um name, que será referenciado na opção notify das tarefas que o acionam.

Exemplo de Definição de Handler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
- name: Configurar o Servidor Web
  hosts: webservers
  become: yes

  tasks:
    - name: Atualizar arquivo de configuração do Apache
      copy:
        src: /caminho/local/httpd.conf
        dest: /etc/httpd/conf/httpd.conf
      notify: Reiniciar Apache

  handlers:
    - name: Reiniciar Apache
      service:
        name: httpd
        state: restarted

Neste exemplo:

  • A tarefa Atualizar arquivo de configuração do Apache copia o arquivo de configuração.
  • A opção notify ativa o handler Reiniciar Apache se o arquivo foi atualizado.
  • O handler Reiniciar Apache é executado ao final do playbook, apenas se a tarefa de cópia tiver feito uma alteração.

8.3 Usando Múltiplos Handlers

Você pode configurar vários handlers em um playbook, cada um sendo notificado por diferentes tarefas ou pela mesma tarefa. Isso é útil para serviços que dependem de várias configurações.

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
- name: Configuração do Servidor Web
  hosts: webservers
  become: yes

  tasks:
    - name: Atualizar arquivo de configuração principal
      copy:
        src: /caminho/local/httpd.conf
        dest: /etc/httpd/conf/httpd.conf
      notify:
        - Reiniciar Apache

    - name: Atualizar arquivo de configuração do site
      copy:
        src: /caminho/local/vhost.conf
        dest: /etc/httpd/conf.d/vhost.conf
      notify:
        - Reiniciar Apache
        - Verificar Firewall

  handlers:
    - name: Reiniciar Apache
      service:
        name: httpd
        state: restarted

    - name: Verificar Firewall
      command: firewall-cmd --reload

Neste exemplo:

  • Ambas as tarefas de atualização de configuração podem notificar o handler Reiniciar Apache.
  • A segunda tarefa também notifica o handler Verificar Firewall para recarregar as configurações do firewall se houver uma mudança.

8.4 Condicionais com Handlers

Assim como em tarefas regulares, os handlers podem usar condicionais. Veja um exemplo em que o handler Reiniciar Nginx só é executado se o sistema operacional for baseado em Debian:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
- name: Configurar Nginx
  hosts: webservers
  become: yes

  tasks:
    - name: Atualizar configuração do Nginx
      copy:
        src: /caminho/local/nginx.conf
        dest: /etc/nginx/nginx.conf
      notify: Reiniciar Nginx

  handlers:
    - name: Reiniciar Nginx
      service:
        name: nginx
        state: restarted
      when: ansible_os_family == "Debian"

Neste exemplo:

  • O handler Reiniciar Nginx só será executado em sistemas Debian/Ubuntu.

8.5 Handlers e a Ordem de Execução

Handlers são executados ao final da execução das tarefas principais. Se múltiplas tarefas notificarem o mesmo handler, ele será executado apenas uma vez, independentemente do número de notificações.

Isso é importante para:

  • Eficiência: Evita reinicializações repetidas e desnecessárias.
  • Estabilidade: Garante que todas as mudanças estejam aplicadas antes do reinício do serviço.

8.6 Exemplo Prático: Playbook Completo com Handlers

Vamos criar um playbook que configura um servidor web com Apache. Ele instala o Apache, copia arquivos de configuração e usa handlers para reiniciar o Apache apenas se ocorrerem mudanças.

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
- name: Configuração do Servidor Web com Apache
  hosts: webservers
  become: yes

  tasks:
    - name: Instalar Apache
      apt:
        name: apache2
        state: present
        update_cache: yes

    - name: Copiar arquivo de configuração principal do Apache
      copy:
        src: /caminho/local/apache2.conf
        dest: /etc/apache2/apache2.conf
      notify: Reiniciar Apache

    - name: Copiar configuração de site padrão
      copy:
        src: /caminho/local/000-default.conf
        dest: /etc/apache2/sites-available/000-default.conf
      notify: Reiniciar Apache

  handlers:
    - name: Reiniciar Apache
      service:
        name: apache2
        state: restarted

Neste playbook:

  • O Apache é instalado e configurado.
  • Os arquivos de configuração são copiados, acionando o handler Reiniciar Apache apenas se houverem mudanças.
  • O Apache é reiniciado uma única vez após todas as tarefas de cópia serem executadas e, somente se necessário.

8.7 Boas Práticas com Handlers

  1. Nomeie Handlers de Forma Descritiva: Escolha nomes que indicam claramente o que o handler faz (ex: Reiniciar Apache).
  2. Use Handlers para Ações Dependentes de Estado: Utilize handlers para tarefas que só precisam ser executadas se houverem mudanças, como reiniciar ou recarregar serviços.
  3. Evite Notificações Desnecessárias: Sempre que possível, minimize as notificações para não sobrecarregar a execução do playbook com handlers desnecessários.

Resumo da Seção 8

Nessa seção, você aprendeu:

  • O que são handlers no Ansible e como eles ajudam a reagir a mudanças de estado.
  • Como configurar handlers e notificá-los em tarefas, garantindo que eles só sejam executados se necessário.
  • Usar múltiplos handlers e combinar notificações, bem como aplicar condicionais aos handlers.
  • Exemplo prático de playbook com handlers para reiniciar serviços de forma eficiente.

Seção 9: Roles: Estrutura Modular para Playbooks

Objetivo:

Explicar o conceito de roles no Ansible e como usá-las para modularizar playbooks, tornando-os mais organizados e reutilizáveis em ambientes de desenvolvimento, teste e produção.

9.1 O Que São Roles no Ansible?

Roles são uma maneira de organizar playbooks no Ansible, permitindo dividir uma configuração em componentes menores e reutilizáveis. Cada role pode ser vista como um conjunto de tarefas, variáveis, templates e arquivos que, juntos, definem a configuração de uma parte específica do sistema. Elas ajudam a manter o código limpo e modular, especialmente em ambientes maiores.

9.2 Estrutura de uma Role

Uma role possui uma estrutura de diretórios específica, onde cada parte da configuração (tarefas, variáveis, arquivos, templates) fica em um local definido. A estrutura típica de uma role inclui os seguintes diretórios:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
roles/
└── nome_da_role/
    ├── tasks/          # Definem as tarefas principais
    │   └── main.yml
    ├── handlers/       # Define os handlers usados
    │   └── main.yml
    ├── vars/           # Variáveis específicas para a role
    │   └── main.yml
    ├── defaults/       # Variáveis padrão que podem ser sobrescritas
    │   └── main.yml
    ├── files/          # Arquivos estáticos a serem copiados
    ├── templates/      # Arquivos templates com variáveis Jinja2
    └── meta/           # Dependências e metadados da role
        └── main.yml

Explicação da Estrutura:

  • tasks: Contém o arquivo main.yml, onde as tarefas principais são definidas.
  • handlers: Contém main.yml, onde os handlers da role são definidos.
  • vars e defaults: Contêm variáveis. defaults possui variáveis padrão que podem ser sobrescritas, enquanto vars define variáveis específicas para a role.
  • files: Contém arquivos que serão copiados diretamente para o sistema remoto.
  • templates: Armazena templates Jinja2 que serão processados antes de serem aplicados.
  • meta: Define metadados da role, como dependências de outras roles.

9.3 Criando uma Role

Vamos criar uma role chamada apache para configurar o servidor web Apache. Suponha que temos o seguinte diretório de projeto:

1
2
3
4
project/
├── playbook.yml
└── roles/
    └── apache/

Passo 1: Estrutura da Role

Use o comando ansible-galaxy init para gerar a estrutura da role automaticamente:

1
ansible-galaxy init roles/apache

Esse comando cria todos os diretórios necessários dentro de roles/apache.

Passo 2: Definir Tarefas (Arquivo tasks/main.yml)

No arquivo roles/apache/tasks/main.yml, vamos definir as tarefas para instalar e configurar o Apache:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# roles/apache/tasks/main.yml
- name: Instalar Apache
  apt:
    name: apache2
    state: present
    update_cache: yes

- name: Copiar Configuração do Apache
  template:
    src: apache2.conf.j2
    dest: /etc/apache2/apache2.conf
  notify: Reiniciar Apache

- name: Iniciar e Habilitar Apache
  service:
    name: apache2
    state: started
    enabled: yes

Passo 3: Definir Handlers (Arquivo handlers/main.yml)

No arquivo roles/apache/handlers/main.yml, defina o handler para reiniciar o Apache:

1
2
3
4
5
# roles/apache/handlers/main.yml
- name: Reiniciar Apache
  service:
    name: apache2
    state: restarted

Passo 4: Configurar Variáveis Padrão (Arquivo defaults/main.yml)

No arquivo roles/apache/defaults/main.yml, defina variáveis padrão para a role, como o nome do pacote do Apache:

1
2
# roles/apache/defaults/main.yml
apache_package: apache2

Passo 5: Criar um Template (Arquivo templates/apache2.conf.j2)

No diretório roles/apache/templates, crie um arquivo apache2.conf.j2, que será o template da configuração do Apache:

1
2
3
# roles/apache/templates/apache2.conf.j2
# Exemplo de configuração do Apache usando Jinja2
ServerName {{ inventory_hostname }}

Esse template utiliza a variável inventory_hostname, que é uma variável do Ansible que contém o nome do host.

9.4 Utilizando a Role em um Playbook

Agora que a role apache está configurada, vamos criar um playbook para utilizá-la. No arquivo playbook.yml, inclua a role apache:

1
2
3
4
5
6
# playbook.yml
- name: Configuração do Servidor Web
  hosts: webservers
  become: yes
  roles:
    - apache

9.5 Variáveis Específicas de Role

Roles são modulares, mas também flexíveis. Variáveis definidas em defaults/main.yml podem ser sobrescritas diretamente no playbook ou no inventário.

1
2
3
4
5
6
7
8
# playbook.yml
- name: Configuração do Servidor Web com Variável Sobrescrita
  hosts: webservers
  become: yes
  roles:
    - role: apache
      vars:
        apache_package: httpd  # Sobrescrevendo para um sistema Red Hat

Aqui, o apache_package foi sobrescrito para instalar o httpd em sistemas Red Hat/CentOS.

9.6 Usando Dependências de Roles

Dependências permitem que uma role exija outras roles para serem executadas antes dela. Essas dependências são configuradas no arquivo meta/main.yml.

Exemplo de Dependência de Role:

No arquivo roles/apache/meta/main.yml, defina a dependência para que a role firewall seja executada antes de apache:

1
2
3
# roles/apache/meta/main.yml
dependencies:
  - role: firewall

Isso garante que a role firewall seja aplicada antes da configuração do Apache, ideal para aplicar configurações de segurança previamente.

9.7 Exemplo Prático: Playbook com Múltiplas Roles

Vamos criar um playbook que usa duas roles: apache e firewall.

1
2
3
4
5
6
7
8
9
10
# playbook.yml
- name: Configuração Completa do Servidor com Apache e Firewall
  hosts: webservers
  become: yes

  roles:
    - role: firewall
    - role: apache
      vars:
        apache_package: apache2

Este playbook:

  • Aplica a role firewall primeiro para configurar as regras de segurança.
  • Em seguida, aplica a role apache para instalar e configurar o servidor web.

9.8 Boas Práticas para Usar Roles

  1. Estrutura Modular: Divida configurações em roles menores e reutilizáveis (ex.: apache, mysql, nginx).
  2. Use defaults para Variáveis Padrão: Defina variáveis padrão em defaults/main.yml e permita que sejam sobrescritas, facilitando a customização.
  3. Agrupe Tarefas Relacionadas: Coloque tarefas de configuração específicas em roles e defina dependências quando necessário.
  4. Templates e Arquivos em Diretórios Adequados: Mantenha arquivos e templates em files/ e templates/ para fácil acesso e modularidade.

Resumo da Seção 9

Nessa seção, você aprendeu:

  • O que são roles no Ansible e como elas ajudam a modularizar configurações.
  • Estrutura de uma role e a finalidade de cada diretório e arquivo.
  • Como criar uma role do Apache com tarefas, handlers e templates.
  • Exemplo prático de utilização de roles em um playbook, incluindo a definição de dependências entre roles.

Seção 10: Gerenciamento de Secrets e Vault do Ansible

Objetivo:

Demonstrar o uso do Ansible Vault para gerenciar dados sensíveis, incluindo a criação, criptografia e descriptografia de arquivos de variáveis e playbooks. Vamos explorar boas práticas para proteção de secrets e integração segura de dados no Ansible.

10.1 O Que é o Ansible Vault?

O Ansible Vault é uma ferramenta integrada ao Ansible que permite criptografar e proteger dados sensíveis diretamente nos arquivos de configuração. Ele é particularmente útil para:

  • Proteger Senhas e Tokens de API: Dados confidenciais podem ser criptografados para evitar exposição acidental.
  • Controle de Acesso: Garantir que apenas usuários autorizados possam acessar e modificar secrets.
  • Manutenção de Conformidade: Aumentar a segurança e conformidade em ambientes de produção.

10.2 Criptografando Arquivos com o Ansible Vault

Você pode criptografar qualquer arquivo do Ansible, como arquivos de inventário, arquivos de variáveis (group_vars, host_vars) e até mesmo playbooks completos.

Criando um Novo Arquivo Criptografado

Para criar um novo arquivo criptografado, use o comando ansible-vault create, que solicitará uma senha e abrirá um editor para adicionar dados confidenciais.

1
ansible-vault create group_vars/producao/vault.yml

Exemplo de conteúdo em vault.yml:

1
2
3
# group_vars/producao/vault.yml
api_key: "12345abcde"
db_password: "senha_super_secreta"

Após salvar o arquivo, ele estará criptografado e seguro.

Criptografando um Arquivo Existente

Para criptografar um arquivo existente, use ansible-vault encrypt seguido do nome do arquivo:

1
ansible-vault encrypt group_vars/producao/vault.yml

Esse comando criptografará o arquivo e substituirá o conteúdo por uma versão protegida.

10.3 Utilizando Variáveis Criptografadas em Playbooks

Uma vez criptografadas, as variáveis podem ser usadas em playbooks como qualquer outra variável.

Exemplo de Uso em Playbook:

Suponha que temos um arquivo vault.yml com uma variável db_password. No playbook, utilizamos essa variável como qualquer outra:

1
2
3
4
5
6
7
8
9
10
11
- name: Configuração de Banco de Dados
  hosts: dbservers
  become: yes

  tasks:
    - name: Criar Configuração com Senha Criptografada
      template:
        src: db_config.j2
        dest: /etc/db_config.conf
      vars:
        db_user: "admin"

Exemplo do Template db_config.j2:

1
2
3
# Template de Configuração do Banco de Dados
usuario={{ db_user }}
senha={{ db_password }}

10.4 Descriptografando e Editando Arquivos Criptografados

Editando Arquivos Criptografados

Para editar um arquivo já criptografado, utilize o comando ansible-vault edit, que solicitará a senha e abrirá o editor padrão para fazer alterações:

1
ansible-vault edit group_vars/producao/vault.yml

Descriptografando um Arquivo

Para descriptografar um arquivo e remover a proteção, use o comando ansible-vault decrypt:

1
ansible-vault decrypt group_vars/producao/vault.yml

Este comando converte o arquivo de volta para o formato original, sem criptografia.

10.5 Executando Playbooks com Arquivos Criptografados

Quando um playbook utiliza variáveis criptografadas, você deve fornecer a senha do Vault ao executar o playbook. Use a opção --ask-vault-pass para inserir a senha manualmente:

1
ansible-playbook playbook.yml --ask-vault-pass

Ou, alternativamente, use um arquivo de senha para automatizar a execução:

1
ansible-playbook playbook.yml --vault-password-file /caminho/para/arquivo_senha

Nota: O arquivo de senha deve ser protegido com permissões restritas, como chmod 600.

10.6 Atualizando a Senha do Vault

Se precisar alterar a senha de criptografia, utilize o comando ansible-vault rekey:

1
ansible-vault rekey group_vars/producao/vault.yml

Esse comando solicitará a senha atual e uma nova senha para o arquivo criptografado.

10.7 Boas Práticas para Uso do Ansible Vault

  1. Use o Vault para Dados Críticos: Apenas dados sensíveis, como senhas, tokens e informações confidenciais, devem ser criptografados.
  2. Automatize com Arquivo de Senha: Utilize o --vault-password-file em pipelines de CI/CD para evitar inserções manuais de senha.
  3. Proteja o Arquivo de Senha: Se optar por usar um arquivo de senha, restrinja suas permissões para garantir que apenas usuários autorizados possam acessá-lo.
  4. Segregue Variáveis Criptografadas: Armazene variáveis sensíveis em arquivos dedicados, como vault.yml, para facilitar o gerenciamento e a segurança.
  5. Treine a Equipe para o Uso do Vault: Certifique-se de que todos saibam como criar, editar e utilizar arquivos protegidos com o Vault.

Exemplo Completo: Playbook com Vault e Secrets

Aqui está um exemplo de playbook que utiliza uma variável criptografada para configurar um banco de dados.

1. Crie o Arquivo Criptografado (vault.yml)

1
ansible-vault create group_vars/producao/vault.yml

Conteúdo de vault.yml:

1
db_password: "senha_super_secreta"

2. Defina o Playbook (configurar_banco.yml)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- name: Configuração de Banco de Dados com Vault
  hosts: dbservers
  become: yes
  vars_files:
    - group_vars/producao/vault.yml

  tasks:
    - name: Instalar MariaDB
      apt:
        name: mariadb-server
        state: present

    - name: Configurar Banco de Dados com Senha do Vault
      template:
        src: db_config.j2
        dest: /etc/mysql/conf.d/db_config.cnf
      vars:
        db_user: "admin"

3. Template para Configuração (db_config.j2)

1
2
3
# Configuração do Banco de Dados
usuario={{ db_user }}
senha={{ db_password }}

4. Executando o Playbook

Execute o playbook com a opção --ask-vault-pass para fornecer a senha do Vault:

1
ansible-playbook configurar_banco.yml --ask-vault-pass

Resumo da Seção 10

Nessa seção, você aprendeu:

  • O que é o Ansible Vault e como ele ajuda a proteger dados sensíveis.
  • Comandos básicos para criar, criptografar, descriptografar e editar arquivos usando o Vault.
  • Como integrar arquivos e variáveis criptografadas em playbooks e templates.
  • Boas práticas para gerenciar secrets de maneira segura com o Ansible Vault.

Seção 11: Debugging e Testes de Playbooks

Objetivo:

Ensinar a usar os comandos e opções de debug e teste do Ansible para identificar, diagnosticar e corrigir problemas nos playbooks, aumentando a confiabilidade das configurações automatizadas.

11.1 Ferramentas de Debugging no Ansible

O Ansible possui várias ferramentas integradas que ajudam a analisar e depurar playbooks e tarefas. Abaixo estão algumas das principais opções para debugging.

11.1.1 Modo Verbose

O modo verbose aumenta o nível de detalhe dos logs de execução. Você pode adicionar várias letras -v para aumentar a verbosidade:

  • -v: Exibe informações básicas de execução.
  • -vv: Exibe detalhes sobre a comunicação entre o Ansible e os hosts.
  • -vvv: Inclui detalhes mais completos e mostra informações de variáveis e comandos.
  • -vvvv: Ativa o modo mais detalhado, útil para identificar erros específicos de SSH e conexão.

Exemplo:

1
ansible-playbook playbook.yml -vvv

11.1.2 Comando --check para Execução Não Destrutiva

O modo --check executa o playbook em modo de simulação (dry run), mostrando o que seria alterado sem realizar modificações no sistema. É útil para verificar se o playbook está configurado corretamente antes de aplicá-lo.

1
ansible-playbook playbook.yml --check

Esse comando mostra o que o Ansible “faria” sem aplicar mudanças reais.

11.1.3 Comando --diff para Comparação de Mudanças

O comando --diff exibe as diferenças entre o estado atual e o estado desejado, permitindo visualizar as alterações que serão feitas. Esse comando é particularmente útil para analisar mudanças em arquivos gerados por templates ou cópia de arquivos.

1
ansible-playbook playbook.yml --diff

Combinação com --check: A combinação --check --diff permite ver as alterações em modo simulado.

11.1.4 Debugging com o Módulo debug

O módulo debug é usado para exibir mensagens de log ou o valor de variáveis durante a execução. Ele é útil para inspecionar valores de variáveis e o fluxo de execução.

Exemplo de Uso do Módulo debug:

1
2
3
4
5
6
- name: Exemplo de Uso do Debug
  hosts: localhost
  tasks:
    - name: Exibir Valor de Variável
      debug:
        msg: "A variável db_password é {{ db_password }}"

No exemplo acima, o valor de db_password será exibido no log de execução, permitindo verificar seu conteúdo.

11.2 Verificação de Sintaxe

Antes de executar um playbook, é possível verificar a sintaxe com o comando --syntax-check, que detecta erros de sintaxe e formatação no YAML, evitando problemas comuns antes da execução.

1
ansible-playbook playbook.yml --syntax-check

11.3 Testes Condicionais com assert

O módulo assert permite verificar se uma condição específica é verdadeira. Se a condição falhar, o Ansible interrompe a execução e exibe uma mensagem de erro. Isso é útil para validar pré-requisitos e garantir que as variáveis estejam corretamente definidas.

Exemplo de Uso do Módulo assert:

1
2
3
4
5
6
7
8
9
- name: Verificar Configuração
  hosts: all

  tasks:
    - name: Verificar se o ambiente é de produção
      assert:
        that:
          - environment == "production"
        fail_msg: "Este playbook  pode ser executado em ambiente de produção."

No exemplo acima, o playbook só será executado se environment for igual a production.

11.4 Parando e Ignorando Tarefas com fail e ignore_errors

11.4.1 Módulo fail

O módulo fail permite interromper a execução com uma mensagem personalizada. Ele é útil para parar a execução quando uma condição crítica não é atendida.

Exemplo de Uso do fail:

1
2
3
4
5
6
7
- name: Exemplo de Condição Crítica
  hosts: localhost
  tasks:
    - name: Parar execução se a variável critical_var não estiver definida
      fail:
        msg: "A variável critical_var é obrigatória!"
      when: critical_var is not defined

11.4.2 Ignorando Erros com ignore_errors

A opção ignore_errors: yes permite ignorar erros em tarefas específicas, permitindo que o playbook continue executando mesmo se uma tarefa falhar.

1
2
3
4
5
6
- name: Exemplo de Ignorar Erros
  hosts: localhost
  tasks:
    - name: Tarefa que pode falhar sem parar o playbook
      command: /bin/falhar
      ignore_errors: yes

Essa abordagem é útil para tarefas não críticas, que não impactam o resultado final.

11.5 Exemplo Prático: Playbook com Debugging e Testes

Vamos criar um playbook que verifica se uma variável obrigatória (environment) está definida, exibe uma mensagem de debug com o valor da variável, e simula uma instalação com --check e --diff.

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 de Servidor com Testes e Debugging
  hosts: webservers
  become: yes

  vars:
    environment: production

  tasks:
    - name: Verificar se o Ambiente está Definido
      assert:
        that:
          - environment is defined
        fail_msg: "A variável 'environment' não está definida!"

    - name: Exibir o Ambiente Configurado
      debug:
        msg: "O ambiente atual é: {{ environment }}"

    - name: Simular Instalação de Pacote
      apt:
        name: nginx
        state: present
      when: environment == "production"

11.6 Boas Práticas para Debugging e Testes

  1. Usar o --check e --diff para Testes Não Destrutivos: Execute sempre em modo de simulação para revisar mudanças antes da aplicação em produção.
  2. Definir Variáveis Claramente: Exiba variáveis e suas condições com o módulo debug para garantir que as variáveis estejam corretas.
  3. Verificar Pré-Requisitos com assert: Use o módulo assert para garantir que pré-requisitos, como variáveis e configurações, estejam definidos corretamente.
  4. Ignorar Erros com Cuidado: Utilize ignore_errors apenas quando realmente necessário para evitar comportamentos inesperados.
  5. Aumentar a Verbosidade em Casos de Erro: Use -vvv ou -vvvv para obter mais informações ao diagnosticar problemas complexos.

Resumo da Seção 11

Nessa seção, você aprendeu:

  • A usar o modo verbose, --check e --diff para debugging e testes em playbooks.
  • A utilizar o módulo debug para inspecionar variáveis e mensagens durante a execução.
  • A validar condições com assert e interromper a execução com fail.
  • A ignorar erros controladamente com ignore_errors.
  • Exemplo prático de um playbook com técnicas de debugging e validação.

Seção 12: Implementação de Pipelines CI/CD com Ansible

Objetivo:

Explicar como integrar o Ansible em pipelines de CI/CD usando ferramentas como GitLab CI, Jenkins e GitHub Actions, automatizando o deploy de infraestrutura e aplicações. Veremos como estruturar um pipeline CI/CD com Ansible, validar e aplicar mudanças em ambientes de maneira segura e automatizada.

12.1 Por Que Usar o Ansible em Pipelines CI/CD?

A integração do Ansible com pipelines CI/CD traz uma série de vantagens para o gerenciamento de infraestrutura:

  • Automação Completa: Com o Ansible em pipelines, configurações são aplicadas automaticamente em todos os ambientes, garantindo consistência.
  • Facilidade de Atualizações: Atualizações de infraestrutura podem ser testadas e aplicadas automaticamente, reduzindo o risco de falhas manuais.
  • Auditoria e Controle de Versão: Com integração a repositórios Git, todo o histórico de mudanças fica registrado e versionado.
  • Rápida Recuperação de Ambientes: Facilita a aplicação rápida de configurações, suportando escalabilidade e recuperação de ambientes.

12.2 Estrutura Básica de um Pipeline CI/CD com Ansible

A estrutura básica de um pipeline CI/CD com Ansible consiste em:

  1. Preparação do Ambiente: Verificar dependências e instalar o Ansible.
  2. Validação do Código: Verificar a sintaxe dos playbooks com --syntax-check.
  3. Execução em Modo de Teste: Executar os playbooks em modo --check para verificar o impacto das mudanças.
  4. Deploy em Ambiente de Teste: Aplicar as mudanças em um ambiente de teste para validação.
  5. Deploy em Produção: Executar os playbooks em produção após as aprovações necessárias.

12.3 Integração do Ansible com GitLab CI

O GitLab CI é uma das plataformas populares para integração e entrega contínuas. Vamos ver um exemplo de configuração para incluir o Ansible em um pipeline GitLab CI.

Exemplo de Arquivo .gitlab-ci.yml com Ansible

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
stages:
  - validate
  - test
  - deploy

variables:
  ANSIBLE_HOST_KEY_CHECKING: "False"

before_script:
  - apt-get update
  - apt-get install -y ansible

validate:
  stage: validate
  script:
    - ansible-playbook playbook.yml --syntax-check

test:
  stage: test
  script:
    - ansible-playbook playbook.yml --check -i inventory/test

deploy:
  stage: deploy
  when: manual
  script:
    - ansible-playbook playbook.yml -i inventory/prod

Explicação do Pipeline:

  • validate: Verifica a sintaxe dos playbooks.
  • test: Executa o playbook em modo --check no ambiente de teste.
  • deploy: Executa o playbook no ambiente de produção. Aqui, o when: manual configura o estágio para que seja executado manualmente, permitindo uma aprovação antes de aplicar mudanças em produção.

12.4 Integração do Ansible com Jenkins

O Jenkins é uma ferramenta de CI/CD amplamente usada e permite automação com Ansible através de jobs configurados ou pipelines declarativos.

Exemplo de Pipeline Declarativo no Jenkins

  1. Instale o Plugin Ansible para Jenkins (opcional, mas recomendado).
  2. Crie um Pipeline Declarativo no Jenkins, utilizando o seguinte código:
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
pipeline {
    agent any

    environment {
        ANSIBLE_HOST_KEY_CHECKING = "False"
    }

    stages {
        stage('Preparation') {
            steps {
                script {
                    sh 'apt-get update && apt-get install -y ansible'
                }
            }
        }

        stage('Validate') {
            steps {
                sh 'ansible-playbook playbook.yml --syntax-check'
            }
        }

        stage('Test') {
            steps {
                sh 'ansible-playbook playbook.yml --check -i inventory/test'
            }
        }

        stage('Deploy') {
            when {
                expression { env.BRANCH_NAME == 'main' }
            }
            steps {
                sh 'ansible-playbook playbook.yml -i inventory/prod'
            }
        }
    }
}

Explicação do Pipeline:

  • Preparation: Instala o Ansible no ambiente.
  • Validate: Valida a sintaxe do playbook.
  • Test: Executa o playbook em modo --check no ambiente de teste.
  • Deploy: Aplica o playbook no ambiente de produção, mas apenas quando a branch principal (main) é atualizada.

12.5 Integração do Ansible com GitHub Actions

GitHub Actions é a ferramenta de CI/CD integrada ao GitHub, facilitando o deploy com Ansible para repositórios armazenados na plataforma.

Exemplo de Arquivo de Workflow (deploy.yml) para GitHub Actions

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: Deploy com Ansible

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
    - name: Checar o Código
      uses: actions/checkout@v2

    - name: Instalar Ansible
      run: sudo apt-get update && sudo apt-get install -y ansible

    - name: Verificar Sintaxe
      run: ansible-playbook playbook.yml --syntax-check

    - name: Teste em Modo Check
      run: ansible-playbook playbook.yml --check -i inventory/test

    - name: Deploy em Produção
      if: github.ref == 'refs/heads/main'
      run: ansible-playbook playbook.yml -i inventory/prod

Explicação do Workflow:

  • Checar o Código: Baixa o código do repositório.
  • Instalar Ansible: Instala o Ansible na máquina runner.
  • Verificar Sintaxe: Executa o comando de verificação de sintaxe.
  • Teste em Modo Check: Executa em modo de simulação no ambiente de teste.
  • Deploy em Produção: Executa o playbook em produção, mas somente em atualizações na branch principal.

12.6 Exemplo Prático de Pipeline CI/CD Completo com Ansible

Aqui está um exemplo prático de um pipeline de CI/CD usando o GitLab CI com um playbook para deploy de uma aplicação web com Nginx.

Estrutura de Arquivos:

1
2
3
4
5
6
project/
├── .gitlab-ci.yml
├── playbook.yml
└── inventory/
    ├── test
    └── prod

Exemplo do Playbook (playbook.yml):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- name: Deploy da Aplicação Web com Nginx
  hosts: webservers
  become: yes

  tasks:
    - name: Instalar Nginx
      apt:
        name: nginx
        state: present
        update_cache: yes

    - name: Copiar Página Inicial
      copy:
        content: "<h1>Bem-vindo ao Nginx!</h1>"
        dest: /var/www/html/index.html

    - name: Iniciar e Habilitar Nginx
      service:
        name: nginx
        state: started
        enabled: yes

Arquivo .gitlab-ci.yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
stages:
  - validate
  - test
  - deploy

before_script:
  - apt-get update && apt-get install -y ansible

validate:
  stage: validate
  script:
    - ansible-playbook playbook.yml --syntax-check

test:
  stage: test
  script:
    - ansible-playbook playbook.yml --check -i inventory/test

deploy:
  stage: deploy
  when: manual
  script:
    - ansible-playbook playbook.yml -i inventory/prod

Boas Práticas para Implementação de CI/CD com Ansible

  1. Separação de Inventários por Ambiente: Mantenha inventários de teste e produção separados para evitar deploys acidentais.
  2. Validação e Teste Antes do Deploy: Inclua estágios de validação e teste para verificar o playbook antes de aplicá-lo em produção.
  3. Controle de Versão: Sempre execute pipelines a partir de branches específicas e use controle de versionamento para aprovações.
  4. Logs Detalhados: Utilize o modo verbose (-vvv) em produção para logs mais completos.
  5. Uso de Secrets com Vault: Mantenha informações sensíveis em arquivos protegidos com Ansible Vault.

Resumo da Seção 12

Nessa seção, você aprendeu:

  • A importância do Ansible em pipelines CI/CD para deploys automáticos e consistentes.
  • Como configurar

pipelines de CI/CD para Ansible no GitLab CI, Jenkins e GitHub Actions.

  • Exemplo prático de um pipeline CI/CD completo com Ansible para deploy de uma aplicação web com Nginx.
  • Boas práticas para integrar Ansible em pipelines CI/CD de forma segura e eficiente.

Seção 13: Configuração de Infraestrutura com Ansible e Cloud Providers

Objetivo:

Demonstrar como usar o Ansible para gerenciar recursos em nuvem, incluindo o provisionamento e configuração de instâncias em AWS, Azure e Google Cloud. Vamos abordar exemplos práticos de automação de infraestrutura na nuvem e explorar os módulos específicos de cada provedor.

13.1 Visão Geral dos Módulos de Nuvem no Ansible

O Ansible oferece módulos específicos para cada provedor de nuvem, permitindo que você provisione, configure e gerencie recursos remotamente. Esses módulos facilitam operações como:

  • Provisionamento de Instâncias: Criar e configurar instâncias de máquinas virtuais (EC2, VMs).
  • Gerenciamento de Redes: Configurar VPCs, sub-redes, grupos de segurança e regras de firewall.
  • Automação de Serviços: Criar e gerenciar recursos como bancos de dados, armazenamento e balanceadores de carga.

13.2 Pré-requisitos para Usar o Ansible com Provedores de Nuvem

Para começar, você deve:

  1. Configurar as Credenciais de Acesso: Crie uma conta com permissões adequadas no provedor de nuvem e obtenha as credenciais (ex.: Access Keys na AWS).
  2. Instalar Dependências: Instale pacotes ou bibliotecas que permitem o Ansible se comunicar com o provedor de nuvem (ex.: boto3 para AWS).

Instalação de Dependências:

1
2
3
4
5
6
7
8
# AWS
pip install boto3 botocore

# Azure
pip install azure-mgmt-compute azure-mgmt-network azure-identity

# Google Cloud
pip install google-auth google-auth-oauthlib google-api-python-client

13.3 Provisionando Recursos na AWS com Ansible

A AWS possui uma ampla gama de módulos no Ansible, incluindo módulos para criar instâncias EC2, gerenciar grupos de segurança e configurar outros serviços.

Exemplo: Provisionamento de Instância EC2

Pré-requisitos:

  • Configurar as credenciais AWS em ~/.aws/credentials ou exportá-las como variáveis de ambiente (AWS_ACCESS_KEY_ID e AWS_SECRET_ACCESS_KEY).

Exemplo de Playbook:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
- name: Provisionamento de Instância EC2 na AWS
  hosts: localhost
  gather_facts: no

  tasks:
    - name: Criar Instância EC2
      amazon.aws.ec2_instance:
        name: "servidor-web"
        key_name: "minha-chave-aws"
        instance_type: "t2.micro"
        region: "us-east-1"
        image_id: "ami-12345678"
        wait: yes
      register: ec2_info

    - name: Exibir Informações da Instância
      debug:
        msg: "Instância criada com ID {{ ec2_info.instance_ids }}"

Explicação do Playbook:

  • amazon.aws.ec2_instance: Este módulo cria uma nova instância EC2 com as especificações fornecidas.
  • register: Armazena as informações da instância criada na variável ec2_info.
  • debug: Exibe o ID da instância criada.

Configurando Grupos de Segurança na AWS

Os grupos de segurança são fundamentais para configurar as regras de entrada e saída de uma instância EC2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- name: Configurar Grupo de Segurança na AWS
  hosts: localhost
  gather_facts: no

  tasks:
    - name: Criar Grupo de Segurança
      amazon.aws.ec2_security_group:
        name: "web-server-sg"
        description: "Grupo de Segurança para Servidor Web"
        vpc_id: "vpc-12345678"
        rules:
          - proto: tcp
            from_port: 80
            to_port: 80
            cidr_ip: "0.0.0.0/0"
        region: "us-east-1"
      register: sg_info

    - name: Exibir ID do Grupo de Segurança
      debug:
        msg: "Grupo de Segurança criado com ID {{ sg_info.group_id }}"

13.4 Provisionando Recursos na Azure com Ansible

A Azure possui módulos no Ansible para gerenciar VMs, redes virtuais e outros serviços.

Exemplo: Provisionamento de VM na Azure

Pré-requisitos:

  • Configurar as credenciais do Azure utilizando az login ou exportar como variáveis de ambiente (AZURE_CLIENT_ID, AZURE_SECRET, etc.).

Exemplo de Playbook:

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: Provisionamento de VM na Azure
  hosts: localhost
  gather_facts: no

  tasks:
    - name: Criar Grupo de Recursos
      azure.azcollection.azure_rm_resourcegroup:
        name: "meu-grupo-recursos"
        location: "East US"

    - name: Criar VM na Azure
      azure.azcollection.azure_rm_virtualmachine:
        resource_group: "meu-grupo-recursos"
        name: "meu-servidor-web"
        vm_size: "Standard_B1s"
        admin_username: "azureuser"
        admin_password: "senha-segura"
        image:
          offer: "UbuntuServer"
          publisher: "Canonical"
          sku: "18.04-LTS"
          version: "latest"
        network_interfaces:
          - name: "meu-nic"
        location: "East US"

Explicação do Playbook:

  • azure.azcollection.azure_rm_resourcegroup: Cria um grupo de recursos na Azure.
  • azure.azcollection.azure_rm_virtualmachine: Cria uma VM Ubuntu com tamanho e configurações definidos.

13.5 Provisionando Recursos no Google Cloud com Ansible

No Google Cloud, o Ansible permite criar instâncias, gerenciar redes e configurar firewalls.

Exemplo: Provisionamento de Instância no Google Cloud

Pré-requisitos:

  • Configurar credenciais do Google Cloud e definir a variável de ambiente GOOGLE_APPLICATION_CREDENTIALS com o caminho para o arquivo JSON das credenciais.

Exemplo de Playbook:

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: Provisionamento de Instância no Google Cloud
  hosts: localhost
  gather_facts: no

  tasks:
    - name: Criar Instância GCE
      google.cloud.gcp_compute_instance:
        name: "meu-servidor-web"
        machine_type: "f1-micro"
        zone: "us-central1-a"
        project: "meu-projeto-gcp"
        auth_kind: "serviceaccount"
        image: "debian-cloud/debian-9"
        disks:
          - auto_delete: true
            boot: true
            source: "projects/debian-cloud/global/images/family/debian-9"
        network_interfaces:
          - network: "default"
            access_configs:
              - name: "External NAT"
                type: "ONE_TO_ONE_NAT"
      register: gce_info

    - name: Exibir IP Externo da Instância
      debug:
        msg: "IP Externo da Instância: {{ gce_info.instance.networkInterfaces[0].accessConfigs[0].natIP }}"

13.6 Boas Práticas para Gerenciamento de Infraestrutura em Nuvem com Ansible

  1. Separação de Ambientes: Utilize inventários específicos para ambientes (teste, produção) e controle o deploy para cada um de forma independente.
  2. Variáveis e Credenciais Seguras: Utilize o Ansible Vault para proteger informações sensíveis, como chaves e senhas.
  3. Automatize Configurações de Rede: Configure grupos de segurança, firewalls e redes virtualizadas diretamente no Ansible.
  4. Gerenciamento de Estado: Registre o estado dos recursos provisionados para evitar criação duplicada.
  5. Tags e Labels: Adicione tags para identificar e organizar os recursos, facilitando a administração e o faturamento.

Resumo da Seção 13

Nessa seção, você aprendeu:

  • Como utilizar o Ansible para provisionar e gerenciar recursos em nuvem, incluindo AWS, Azure e Google Cloud.
  • Exemplo prático de playbooks para provisionar instâncias e configurar redes em diferentes provedores de nuvem.
  • Boas práticas para automação de infraestrutura em nuvem com Ansible, incluindo separação de ambientes e uso seguro de credenciais.

Seção 14: Monitoramento e Log de Execuções do Ansible

Objetivo:

Ensinar a configurar logs detalhados para execuções do Ansible e explorar ferramentas e plugins que ajudam a monitorar as tarefas em tempo real, possibilitando auditoria e rastreamento de alterações na infraestrutura.

14.1 Configurando Logs no Ansible

O Ansible permite configurar o nível de log e o local onde os registros serão salvos. Esses logs são úteis para depuração e auditoria das mudanças realizadas na infraestrutura.

Configurando o Arquivo de Log no ansible.cfg

O arquivo ansible.cfg permite especificar onde os logs devem ser salvos. Para ativar logs persistentes, configure o parâmetro log_path no arquivo ansible.cfg.

Exemplo de Configuração do ansible.cfg:

1
2
3
# Arquivo ansible.cfg
[defaults]
log_path = /var/log/ansible/ansible.log

Permissões do Diretório de Log: Certifique-se de que o diretório de log (/var/log/ansible/) tem permissões adequadas, especialmente se for usado por múltiplos usuários ou scripts. Aplique permissões com o comando:

1
2
3
sudo mkdir -p /var/log/ansible
sudo chmod 755 /var/log/ansible
sudo chown $USER:$USER /var/log/ansible/ansible.log

Com o log_path definido, o Ansible salva todos os registros das execuções no arquivo especificado, incluindo informações detalhadas sobre cada tarefa e o estado dos hosts.

14.2 Níveis de Verbosidade

O Ansible permite ajustar a verbosidade dos logs para fornecer mais detalhes conforme necessário. Isso é útil para depurar problemas específicos ou obter uma visão detalhada da execução dos playbooks.

  • -v: Nível básico de detalhes.
  • -vv: Detalhes adicionais, incluindo variáveis.
  • -vvv: Informações detalhadas sobre a comunicação com hosts remotos.
  • -vvvv: Nível mais alto, ideal para diagnósticos completos.

Exemplo de Comando com Verbosidade:

1
ansible-playbook playbook.yml -vvv

A configuração de verbosidade pode ser ajustada conforme necessário para ambientes de produção ou depuração.

14.3 Plugins de Callback para Monitoramento em Tempo Real

Os plugins de callback permitem que o Ansible envie notificações e registros para diferentes sistemas, possibilitando o monitoramento em tempo real. Esses plugins podem integrar o Ansible com serviços de monitoramento, ferramentas de mensagens e sistemas de gerenciamento de logs.

Exemplo de Plugins de Callback Comuns

  1. Callback para Slack: Notifica o Slack sobre o status das execuções, útil para equipes de DevOps.
  2. Callback para Logstash: Envia registros para um sistema de log centralizado com o ELK Stack.
  3. Callback para JSON: Salva os registros em formato JSON para fácil integração com outras ferramentas de análise.

Exemplo de Configuração do Callback JSON:

No arquivo ansible.cfg, habilite o plugin JSON para salvar as saídas de execução em um arquivo JSON.

1
2
[defaults]
stdout_callback = json

Com esta configuração, a saída da execução será salva em JSON, facilitando o uso de ferramentas de análise que consomem esse formato.

14.4 Análise e Auditoria de Logs com Ferramentas de Monitoramento

Logs centralizados ajudam na análise de dados e auditoria. O uso de ferramentas como ELK Stack (Elasticsearch, Logstash e Kibana) permite coletar, visualizar e analisar logs em tempo real.

Integração do Ansible com ELK Stack

  1. Configuração do Logstash: Configure o Logstash para consumir logs do Ansible. Use o plugin file para monitorar o diretório de logs do Ansible.
  2. Configuração do Elasticsearch e Kibana: Envie os dados do Logstash para o Elasticsearch e visualize no Kibana.

Exemplo de Pipeline Logstash:

1
2
3
4
5
6
7
8
9
10
11
12
13
input {
  file {
    path => "/var/log/ansible/ansible.log"
    start_position => "beginning"
  }
}

output {
  elasticsearch {
    hosts => ["http://localhost:9200"]
    index => "ansible-logs"
  }
}

Essa configuração envia logs do Ansible para o Elasticsearch, onde podem ser visualizados e analisados no Kibana, proporcionando um monitoramento robusto em tempo real.

14.5 Boas Práticas para Monitoramento e Log de Execuções

  1. Configurar Logs Persistentes: Configure log_path no ansible.cfg para manter um registro contínuo das execuções.
  2. Ajustar Nível de Verbosidade para Ambientes de Produção: Use -vv ou -vvv para registros mais detalhados ao depurar problemas específicos, mas mantenha verbosidade mínima para produções estáveis.
  3. Usar Plugins de Callback para Integrações: Utilize plugins para enviar notificações a sistemas de monitoramento e chat, como Slack, e-mail ou ELK Stack.
  4. Monitoramento Centralizado com Ferramentas de Log: Implemente ferramentas como ELK Stack para centralizar e analisar logs de forma eficiente.
  5. Automatizar Alertas: Configure alertas com base em logs para receber notificações sobre falhas ou eventos críticos.

Resumo da Seção 14

Nessa seção, você aprendeu:

  • Como configurar logs persistentes e definir o nível de verbosidade no Ansible para acompanhar a execução dos playbooks.
  • A usar plugins de callback para monitoramento em tempo real e integração com sistemas de log.
  • Exemplo de configuração de integração com o ELK Stack para auditoria centralizada.
  • Boas práticas para manter um monitoramento robusto e eficiente das execuções do Ansible.

Seção 15: Práticas Recomendadas e Boas Práticas com Ansible

Objetivo:

Apresentar um conjunto de boas práticas que ajudam a escrever, organizar e manter playbooks, roles e configurações do Ansible. Vamos explorar desde a estruturação de arquivos até práticas de segurança e otimização, visando eficiência e escalabilidade.

15.1 Estruturação de Playbooks e Roles

1. Estruture Playbooks em Blocos Lógicos

Organize os playbooks em blocos lógicos, usando tasks, handlers, vars, files, e templates. Dividir o código em funções claras facilita a leitura e manutenção, especialmente em automações complexas.

Exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
- name: Configuração do Servidor Web
  hosts: webservers
  become: yes

  tasks:
    - name: Instalar Nginx
      apt:
        name: nginx
        state: present
      notify: Reiniciar Nginx

    - name: Configurar Página Inicial
      copy:
        src: index.html
        dest: /var/www/html/index.html

  handlers:
    - name: Reiniciar Nginx
      service:
        name: nginx
        state: restarted

2. Use Roles para Modularização

Divida playbooks grandes em roles menores, com cada role focando em uma função específica (por exemplo, apache, mysql, firewall). Roles facilitam a reutilização e reduzem a complexidade dos playbooks.

15.2 Organização de Variáveis

1. Defina Variáveis Padrão em defaults/main.yml

Use o arquivo defaults/main.yml nas roles para definir valores padrão das variáveis. Isso permite sobrescrever variáveis conforme necessário sem alterar o código da role.

2. Armazene Variáveis Sensíveis com Ansible Vault

Proteja dados confidenciais, como senhas e tokens de API, usando o Ansible Vault. Configure arquivos vault.yml específicos para cada ambiente (desenvolvimento, teste, produção) e proteja-os com senha.

3. Use group_vars e host_vars para Variáveis Específicas

Configure variáveis específicas para grupos ou hosts usando os diretórios group_vars e host_vars. Isso facilita a personalização de configurações para cada ambiente ou servidor.

15.3 Segurança no Ansible

1. Proteja Credenciais com o Vault

Mantenha credenciais e informações sensíveis criptografadas no Ansible Vault. Evite expor essas informações diretamente nos playbooks ou arquivos de inventário.

2. Limite o Uso de become: yes

Utilize become: yes (equivalente ao sudo) apenas em tarefas que realmente exigem permissões elevadas. Excesso de permissões pode expor o sistema a riscos de segurança.

3. Controle de Acesso aos Inventários e Playbooks

Restrinja permissões nos arquivos de inventário e playbooks, evitando que usuários não autorizados tenham acesso a informações confidenciais.

15.4 Idempotência e Testes

1. Escreva Playbooks Idempotentes

Garanta que as tarefas sejam idempotentes, ou seja, que possam ser executadas várias vezes sem causar mudanças adicionais após a primeira execução. Isso evita problemas como duplicação de dados ou configurações incorretas.

2. Teste com --check e --diff

Use o modo --check para testes de simulação e --diff para visualizar mudanças. Realizar testes antes da execução em produção ajuda a evitar erros.

3. Automatize Testes com CI/CD

Integre o Ansible em pipelines CI/CD para automatizar a validação e deploy dos playbooks. Isso garante que as mudanças sejam testadas antes de serem aplicadas.

15.5 Práticas de Otimização

1. Reduza o Uso de command e shell

Sempre que possível, use módulos específicos do Ansible (ex.: apt, yum, service) em vez de command ou shell. Módulos são mais seguros e garantem idempotência.

2. Combine Tarefas Repetitivas com Loops

Utilize loop para aplicar uma mesma tarefa em listas de itens, como pacotes, usuários ou arquivos. Isso reduz a duplicação de código e torna os playbooks mais eficientes.

1
2
3
4
5
6
7
8
- name: Instalar Pacotes Essenciais
  apt:
    name: "{{ item }}"
    state: present
  loop:
    - git
    - curl
    - vim

3. Evite Variáveis Desnecessárias

Limite o uso de variáveis para valores que realmente necessitam de flexibilidade. Variáveis desnecessárias tornam o código mais difícil de manter e podem causar confusão.

15.6 Estruturação de Repositórios Git para Ansible

  1. Organize por Ambientes: Separe diretórios de inventários e arquivos vault.yml para cada ambiente (desenvolvimento, teste, produção).
  2. Use Branches para Controle de Mudanças: Trabalhe com branches específicas para desenvolvimento e produções e utilize revisões de código (pull requests) para controlar as alterações.
  3. Versione Playbooks e Roles: Mantenha um controle de versão dos playbooks e roles para que seja fácil restaurar versões anteriores, se necessário.

Exemplo de Estrutura do Repositório:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
my-ansible-project/
├── playbooks/
│   ├── webserver.yml
│   └── database.yml
├── roles/
│   ├── apache/
│   └── mysql/
├── inventories/
│   ├── dev/
│   ├── test/
│   └── prod/
└── group_vars/
    ├── all.yml
    ├── dev.yml
    └── prod.yml

15.7 Checklist de Boas Práticas para Produção

  • Estrutura Lógica e Modular: Utilize roles para modularizar e organizar as tarefas.
  • Segurança: Proteja informações sensíveis com Ansible Vault e limite o uso de permissões elevadas.
  • Idempotência: Garanta que todas as tarefas possam ser executadas várias vezes sem efeitos colaterais.
  • Documentação: Documente as roles e playbooks para facilitar o entendimento e a manutenção.
  • Auditoria e Monitoramento: Configure logs e centralize-os para auditoria das execuções do Ansible.
  • Controle de Versão: Mantenha playbooks e configurações versionados no Git para controle de mudanças e restauração de versões.

Resumo da Seção 15

Nessa seção, você aprendeu:

  • Como estruturar e modularizar playbooks e roles para maior organização.
  • Práticas recomendadas para segurança, incluindo o uso do Ansible Vault e restrição de permissões.
  • A importância de idempotência, otimização e testes para garantir confiabilidade e eficiência nas automações.
  • Estruturação de repositórios Git e controle de versões para facilitar o trabalho em equipe e auditoria.
  • Checklist de boas práticas para ambientes de produção.

Conclusão do Tutorial

Com este tutorial, você obteve uma visão completa sobre o uso do Ansible para automação de infraestrutura. Abordamos desde a configuração inicial e conceitos fundamentais até práticas avançadas para automação em ambientes complexos, incluindo integração com CI/CD, gerenciamento de nuvem e segurança. Aplicando estas boas práticas e recursos avançados, você será capaz de construir, gerenciar e escalar ambientes de forma eficiente e segura.


This post is licensed under CC BY 4.0 by the author.