Post

Guia Completo: Usando Roles no Ansible para Automação e Organização de Ambientes

Guia Completo: Usando Roles no Ansible para Automação e Organização de Ambientes

Introdução

Neste tutorial, exploramos em profundidade o uso de roles no Ansible, uma das práticas mais eficazes para organizar e modularizar configurações de infraestrutura. As roles no Ansible permitem dividir uma configuração complexa em componentes reutilizáveis, facilitando a manutenção e escalabilidade em ambientes de produção.

Ao longo deste guia, cobrimos desde a estrutura básica e criação de uma role até o uso avançado de dependências, variáveis e integração com o Ansible Galaxy para download e compartilhamento de roles com a comunidade. O tutorial está estruturado para oferecer uma visão completa que atende tanto iniciantes quanto usuários avançados, abordando as seguintes etapas:

  • A estrutura e organização de uma role,
  • O uso de variáveis, templates e arquivos estáticos,
  • Configuração e uso de handlers e dependências,
  • Implementação de roles em playbooks e gerenciamento de variáveis,
  • Boas práticas para manutenção, segurança e controle de versões,
  • Compartilhamento e download de roles no Ansible Galaxy.

Com essas instruções, você terá um guia abrangente para automatizar suas operações de TI com eficiência, promovendo consistência e organização em ambientes de grande escala.


Índice


1. Introdução ao Conceito de Roles no Ansible

Objetivo:

Apresentar o conceito de roles no Ansible e como elas auxiliam na organização e reutilização de código. As roles oferecem uma forma de modularizar as configurações, tornando o gerenciamento de ambientes complexos mais prático e eficiente.

Conteúdo:

  1. O Que São Roles no Ansible?
    • Em projetos complexos, configurar um servidor pode envolver diversas tarefas, como a instalação de pacotes, criação de arquivos de configuração, definição de variáveis e a execução de handlers para reiniciar serviços. Para organizar essas tarefas de forma eficiente, o Ansible utiliza o conceito de roles.
    • Uma role é um conjunto de recursos organizados para realizar uma configuração específica. Em vez de definir todas as tarefas em um único playbook, as roles permitem dividir cada serviço (como servidor web, banco de dados, firewall) em módulos, que podem ser reaproveitados em múltiplos ambientes e contextos.
    • Uma role agrupa tarefas, variáveis, arquivos, templates e handlers em uma estrutura pré-definida. Isso facilita a reutilização e a manutenção, permitindo criar uma configuração em um único local e aplicá-la a diferentes hosts ou grupos.
  2. Vantagens das Roles para Reuso, Manutenção e Padronização
    • Reuso: Com roles, uma configuração para um serviço específico (por exemplo, Nginx ou MySQL) pode ser reutilizada em diferentes playbooks, garantindo consistência nas configurações.
    • Manutenção: Como cada role é independente, é mais fácil identificar, atualizar ou corrigir configurações específicas de um serviço sem modificar o restante do projeto.
    • Padronização: Roles permitem que toda a equipe utilize a mesma estrutura e configuração, garantindo que todos os serviços sigam padrões bem definidos.
    • Escalabilidade: Em ambientes grandes, roles tornam o Ansible mais escalável, pois as configurações são modulares e facilmente extensíveis para novos serviços e componentes.
  3. Estrutura Básica de uma Role no Ansible
    • Cada role no Ansible segue uma estrutura de diretórios específica, que organiza as diferentes partes da configuração:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      
      nome_da_role/
      ├── tasks/              # Contém as tarefas principais da role
      │   └── main.yml
      ├── handlers/           # Define handlers para ações condicionalmente necessárias (como reiniciar um serviço)
      │   └── main.yml
      ├── templates/          # Armazena templates Jinja2 para arquivos de configuração dinâmicos
      ├── files/              # Contém arquivos fixos a serem copiados para o host
      ├── vars/               # Define variáveis específicas da role
      │   └── main.yml
      ├── defaults/           # Define variáveis padrão, com menor precedência
      │   └── main.yml
      ├── meta/               # Contém metadados da role, como dependências
      │   └── main.yml
      └── README.md           # Documentação da role, com informações de uso e configuração
      
    • Explicação dos Principais Diretórios:
      • tasks/: Armazena as tarefas principais da role. Geralmente, o arquivo main.yml contém a sequência de ações executadas.
      • handlers/: Define handlers para ações que devem ocorrer em resposta a mudanças, como reiniciar um serviço após atualização de configuração.
      • templates/: Contém arquivos de configuração dinâmicos, que podem ser renderizados com variáveis do Ansible usando a sintaxe Jinja2.
      • files/: Armazena arquivos fixos, que são copiados diretamente para o host remoto.
      • vars/ e defaults/: Contêm variáveis para configuração da role, sendo que as variáveis em defaults/ têm menor precedência e podem ser sobrescritas com mais facilidade.
      • meta/: Armazena metadados da role, incluindo dependências que serão executadas antes dela.
  4. Exemplo de Quando Usar Roles
    • Imagine que você precisa configurar servidores web e bancos de dados em diferentes ambientes (produção, teste e desenvolvimento). Em vez de duplicar as mesmas configurações em diferentes playbooks, você pode criar uma role para cada serviço (webserver, database) e configurá-los de maneira modular.
    • Dessa forma, quando precisar realizar uma atualização ou corrigir um erro, basta modificar a role, e todas as instâncias que utilizam essa role serão atualizadas automaticamente.

Tabela Resumida das Vantagens das Roles

Vantagem Descrição
Reuso Permite reutilizar configurações de serviços em múltiplos playbooks, garantindo consistência.
Manutenção Facilita a atualização e correção de configurações sem interferir em outros componentes.
Padronização Ajuda a garantir que todos os serviços sigam padrões definidos, melhorando a colaboração da equipe.
Escalabilidade Torna o gerenciamento de ambientes complexos mais eficiente e modular.

2. Estrutura de Diretórios e Arquivos de uma Role

Objetivo:

Explicar a estrutura de arquivos e diretórios em uma role no Ansible, detalhando o propósito de cada diretório e como ele organiza as partes essenciais da configuração de uma role.

Conteúdo:

  1. Estrutura de Diretórios de uma Role no Ansible
    • O Ansible define uma estrutura de diretórios específica para roles, que facilita o gerenciamento de cada componente (tarefas, variáveis, templates, arquivos e handlers) de forma organizada e modular.
    • Estrutura de diretórios típica de uma role:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      
      nome_da_role/
      ├── tasks/
      │   └── main.yml
      ├── handlers/
      │   └── main.yml
      ├── templates/
      ├── files/
      ├── vars/
      │   └── main.yml
      ├── defaults/
      │   └── main.yml
      ├── meta/
      │   └── main.yml
      └── README.md
      
  2. Diretórios Principais e Suas Funções
    • tasks/: Armazena as tarefas principais da role. O arquivo tasks/main.yml é o ponto de entrada, onde as ações que a role executa são definidas.
    • handlers/: Contém os handlers, que são tarefas acionadas apenas quando chamadas por uma notificação (por exemplo, reiniciar um serviço após uma atualização).
    • templates/: Diretório para arquivos dinâmicos, geralmente configurados como templates Jinja2, que utilizam variáveis do Ansible para gerar configurações personalizadas.
    • files/: Armazena arquivos fixos, como pacotes, scripts ou configurações, que podem ser copiados para os hosts sem modificação.
    • vars/: Define variáveis específicas da role. As variáveis em vars/main.yml têm precedência sobre as definidas em defaults/.
    • defaults/: Contém variáveis padrão, que podem ser sobrescritas em níveis mais altos (por exemplo, no inventário ou no playbook). Esse arquivo (defaults/main.yml) define as configurações padrão da role.
    • meta/: Define metadados sobre a role, incluindo dependências de outras roles que devem ser executadas antes dela.
    • README.md: Arquivo de documentação onde você pode descrever o objetivo da role, as variáveis esperadas, e como ela deve ser utilizada.
  3. Exemplo Prático de Estrutura para Configurar um Servidor Web
    • Vamos criar a estrutura básica para uma role chamada webserver, que configurará um servidor Nginx. Cada diretório terá sua função específica no processo de configuração.

    • Estrutura da Role webserver:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      
      webserver/
      ├── tasks/
      │   └── main.yml
      ├── handlers/
      │   └── main.yml
      ├── templates/
      │   └── nginx.conf.j2
      ├── files/
      │   └── index.html
      ├── vars/
      │   └── main.yml
      ├── defaults/
      │   └── main.yml
      ├── meta/
      │   └── main.yml
      └── README.md
      
    • Conteúdo dos Arquivos:
      • tasks/main.yml: Define as tarefas principais da configuração do servidor Nginx.

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        
        ---
        - name: Instalar o pacote Nginx
          apt:
            name: nginx
            state: present
               
        - name: Copiar o arquivo de configuração do Nginx
          template:
            src: nginx.conf.j2
            dest: /etc/nginx/nginx.conf
          notify: Reiniciar Nginx
               
        - name: Copiar a página inicial
          copy:
            src: index.html
            dest: /var/www/html/index.html
        
      • handlers/main.yml: Define um handler que reinicia o Nginx após qualquer alteração relevante.

        1
        2
        3
        4
        5
        
        ---
        - name: Reiniciar Nginx
          service:
            name: nginx
            state: restarted
        
      • templates/nginx.conf.j2: Template para o arquivo de configuração do Nginx. Usamos variáveis para personalizar as configurações.
        1
        2
        3
        4
        5
        6
        7
        8
        
        server {
            listen ;
            server_name ;
            location / {
                root /var/www/html;
                index index.html index.htm;
            }
        }
        
      • files/index.html: Arquivo estático de exemplo para a página inicial.

        1
        2
        3
        4
        
        <html>
          <head><title>Bem-vindo ao Nginx!</title></head>
          <body><h1>Página Inicial do Servidor Nginx</h1></body>
        </html>
        
      • vars/main.yml: Define variáveis específicas da role, que são aplicadas automaticamente ao executar a role.

        1
        2
        3
        
        ---
        nginx_port: 80
        nginx_server_name: "meusite.com"
        
      • defaults/main.yml: Define variáveis padrão que podem ser substituídas em diferentes contextos (inventário ou playbook).

        1
        2
        3
        
        ---
        nginx_port: 80
        nginx_server_name: "localhost"
        
      • meta/main.yml: Define metadados da role. Neste exemplo, a role não depende de outras, então esse arquivo pode estar vazio ou ter apenas um esboço.

        1
        2
        
        ---
        dependencies: []
        
      • README.md: Documentação que explica o objetivo da role e as variáveis configuráveis. Esse é um exemplo de documentação para o usuário:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        
        # Role `webserver`
        
        Esta role configura o Nginx como servidor web, criando a estrutura básica de configuração e arquivos padrão.
        
        ## Variáveis
        
        - `nginx_port`: Porta onde o Nginx será executado (padrão: 80)
        - `nginx_server_name`: Nome do servidor configurado (padrão: "localhost")
        
        ## Handlers
        
        - `Reiniciar Nginx`: Reinicia o Nginx após alterações no arquivo de configuração.
        
  4. Resumo da Estrutura e Função de Cada Diretório

    Diretório Função Exemplo de Conteúdo
    tasks/ Define as tarefas principais da role main.yml com instalação do Nginx
    handlers/ Define handlers para tarefas condicionais main.yml com reinício do Nginx
    templates/ Armazena templates Jinja2 para arquivos de configuração nginx.conf.j2
    files/ Armazena arquivos fixos para cópia index.html
    vars/ Define variáveis específicas da role main.yml com nginx_port: 80
    defaults/ Define variáveis padrão que podem ser sobrescritas main.yml com valores padrão
    meta/ Define metadados e dependências de outras roles main.yml com lista de dependências

3. Criação de uma Role Simples

Objetivo:

Demonstrar como criar uma role no Ansible para configurar um serviço específico, usando o comando ansible-galaxy init para gerar a estrutura de diretórios e adicionando tarefas para instalar e configurar o Apache como um servidor web básico.

Conteúdo:

  1. Criando uma Role com ansible-galaxy init
    • O Ansible facilita a criação de roles com o comando ansible-galaxy init, que gera automaticamente a estrutura de diretórios padrão para uma role, incluindo pastas como tasks, handlers, templates, files, entre outras.
    • Comando para criar uma role chamada apache:
      1
      
      ansible-galaxy init apache
      
    • Isso cria um diretório apache com a estrutura básica de arquivos e diretórios para a role:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      apache/
      ├── tasks/
      ├── handlers/
      ├── templates/
      ├── files/
      ├── vars/
      ├── defaults/
      ├── meta/
      └── README.md
      
  2. Editando o Arquivo tasks/main.yml para Definir Tarefas
    • A role apache precisa de tarefas para instalar o Apache e configurar seu serviço. Vamos editar o arquivo tasks/main.yml para definir essas ações.
    • Conteúdo de tasks/main.yml:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      
      ---
      - name: Instalar o pacote Apache
        apt:
          name: apache2
          state: present
        when: ansible_os_family == "Debian"
      
      - name: Iniciar e habilitar o serviço Apache
        service:
          name: apache2
          state: started
          enabled: true
      
    • Explicação:
      • A primeira tarefa usa o módulo apt para instalar o Apache (apache2) em sistemas baseados em Debian. O when é uma condicional que garante que a tarefa só seja executada em sistemas que pertençam à família Debian (ex.: Debian, Ubuntu).
      • A segunda tarefa usa o módulo service para iniciar o serviço Apache e garantir que ele seja ativado automaticamente no boot.
  3. Definindo Variáveis para Customizar a Role
    • Variáveis permitem tornar a role mais flexível, permitindo configurar opções sem editar a estrutura de tarefas. As variáveis padrão podem ser definidas no arquivo defaults/main.yml, e outras variáveis específicas no vars/main.yml.
    • Conteúdo de defaults/main.yml:

      1
      2
      3
      
      ---
      apache_port: 80
      apache_server_name: "localhost"
      
    • Explicação:
      • A variável apache_port define a porta em que o Apache será executado (padrão 80) e apache_server_name define o nome do servidor (padrão “localhost”). Essas variáveis podem ser usadas em um template de configuração.
  4. Adicionando um Template para o Arquivo de Configuração
    • Para configurar o Apache de forma customizada, vamos criar um template do arquivo de configuração, usando variáveis que definimos em defaults/main.yml. Esse template será um arquivo Jinja2 dentro de templates/.
    • Criação de templates/apache.conf.j2:

      1
      2
      3
      4
      5
      6
      7
      8
      
      <VirtualHost *:>
          ServerName 
          DocumentRoot /var/www/html
      
          <Directory /var/www/html>
              AllowOverride All
          </Directory>
      </VirtualHost>
      
    • Explicação:
      • Este template cria uma configuração de VirtualHost para o Apache, utilizando as variáveis apache_port e apache_server_name. O diretório /var/www/html é definido como o diretório raiz.
  5. Adicionando o Template em tasks/main.yml
    • Vamos adicionar uma tarefa em tasks/main.yml para copiar o arquivo de configuração gerado pelo template para o local adequado no servidor.
    • Atualização de tasks/main.yml:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      
      ---
      - name: Instalar o pacote Apache
        apt:
          name: apache2
          state: present
        when: ansible_os_family == "Debian"
      
      - name: Configurar o Apache usando template
        template:
          src: apache.conf.j2
          dest: /etc/apache2/sites-available/000-default.conf
        notify: Reiniciar Apache
      
      - name: Habilitar site padrão do Apache
        command: a2ensite 000-default.conf
        notify: Reiniciar Apache
      
      - name: Iniciar e habilitar o serviço Apache
        service:
          name: apache2
          state: started
          enabled: true
      
  6. Configurando Handlers para Reiniciar o Apache
    • Os handlers são tarefas especiais que só são executadas quando notificadas por outras tarefas. Vamos configurar um handler em handlers/main.yml para reiniciar o Apache quando o arquivo de configuração for alterado.
    • Conteúdo de handlers/main.yml:

      1
      2
      3
      4
      5
      
      ---
      - name: Reiniciar Apache
        service:
          name: apache2
          state: restarted
      
  7. Exemplo Completo da Estrutura da Role apache

    • Estrutura da role apache após as edições:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
      apache/
      ├── tasks/
      │   └── main.yml
      ├── handlers/
      │   └── main.yml
      ├── templates/
      │   └── apache.conf.j2
      ├── defaults/
      │   └── main.yml
      └── README.md
      
  8. Testando a Role apache em um Playbook
    • Para usar a role apache, vamos criar um playbook de teste:

      1
      2
      3
      4
      5
      6
      
      ---
      - name: Configurar Servidor Apache
        hosts: webservers
        become: true
        roles:
          - apache
      
    • Execute o playbook com:

      1
      
      ansible-playbook nome_do_playbook.yml -i inventario
      

4. Uso de Variáveis em Roles

Objetivo:

Explicar como configurar variáveis dentro de uma role para tornar as tarefas flexíveis e customizáveis. As variáveis permitem que as roles sejam adaptadas para diferentes cenários sem precisar modificar o código principal das tarefas.

Conteúdo:

  1. Onde Definir Variáveis em uma Role
    • No Ansible, as variáveis de uma role podem ser definidas em dois diretórios principais:
      • defaults/: Variáveis padrão, que têm menor precedência e podem ser facilmente sobrescritas em um playbook ou inventário.
      • vars/: Variáveis específicas de role, com uma precedência mais alta. Essas variáveis geralmente são usadas quando uma role exige valores fixos que raramente serão alterados.
    • O arquivo main.yml dentro de cada diretório (defaults/main.yml e vars/main.yml) armazena essas variáveis.
  2. Diferença entre defaults e vars
    • defaults: Ideal para variáveis padrão que podem ser sobrescritas facilmente em diferentes contextos (playbooks, inventários, etc.). Essas variáveis tornam a role mais flexível.
    • vars: Utilizado para variáveis específicas que têm precedência sobre o que for definido no inventário ou em defaults. São úteis para valores essenciais que a role precisa para funcionar corretamente.
    • Exemplo de uso:

      1
      2
      3
      4
      5
      6
      7
      
      # defaults/main.yml
      apache_port: 80
      apache_server_name: "localhost"
      
      # vars/main.yml
      apache_user: "www-data"
      apache_group: "www-data"
      
  3. Exemplo Prático de Uso de Variáveis para Configurar o Apache
    • Vamos modificar nossa role apache para torná-la mais flexível usando variáveis. Adicionaremos variáveis que permitem customizar a porta do Apache, o nome do servidor e o diretório raiz do site.

    • Conteúdo de defaults/main.yml:

      1
      2
      3
      4
      
      ---
      apache_port: 80
      apache_server_name: "localhost"
      apache_document_root: "/var/www/html"
      
    • Explicação:

      • As variáveis apache_port, apache_server_name e apache_document_root são definidas em defaults/main.yml como valores padrão. Elas podem ser sobrescritas em um playbook ou inventário para adaptar a role a diferentes ambientes.
  4. Usando Variáveis no Template de Configuração
    • No arquivo de template templates/apache.conf.j2, vamos usar essas variáveis para criar uma configuração de servidor Apache personalizada.
    • Conteúdo de templates/apache.conf.j2:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      <VirtualHost *:>
          ServerName 
          DocumentRoot 
      
          <Directory >
              AllowOverride All
              Require all granted
          </Directory>
      </VirtualHost>
      
    • Explicação:
      • O template usa as variáveis apache_port, apache_server_name e apache_document_root para definir a porta, o nome do servidor e o diretório raiz do site. Isso torna o arquivo de configuração flexível e customizável de acordo com as variáveis definidas.
  5. Sobrescrevendo Variáveis em um Playbook
    • Vamos criar um playbook que sobrescreve algumas das variáveis padrão da role apache para personalizar a configuração de um servidor específico.
    • Exemplo de Playbook:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
      ---
      - name: Configuração de Servidor Apache Customizado
        hosts: webservers
        become: true
        roles:
          - role: apache
            vars:
              apache_port: 8080
              apache_server_name: "meusite.com"
              apache_document_root: "/var/www/meusite"
      
    • Explicação:
      • No playbook, sobrescrevemos as variáveis apache_port, apache_server_name e apache_document_root para configurar o Apache em uma porta alternativa (8080), com um nome de servidor personalizado (meusite.com) e um diretório raiz diferente (/var/www/meusite).
  6. Usando Variáveis do Inventário
    • Variáveis também podem ser definidas no inventário, permitindo configurações específicas para cada host ou grupo. Isso permite uma customização detalhada sem alterar a role ou o playbook.
    • Exemplo de Variáveis no Inventário:
      1
      2
      3
      
      [webservers]
      servidor1 apache_port=8081 apache_server_name=servidor1.meusite.com
      servidor2 apache_port=8082 apache_server_name=servidor2.meusite.com
      
    • Explicação:
      • Cada servidor no grupo webservers tem um valor específico para apache_port e apache_server_name, permitindo que cada host tenha sua própria configuração personalizada.
  7. Exemplo Completo da Role com Uso de Variáveis

    • Estrutura da role apache com variáveis:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
      apache/
      ├── tasks/
      │   └── main.yml
      ├── handlers/
      │   └── main.yml
      ├── templates/
      │   └── apache.conf.j2
      ├── defaults/
      │   └── main.yml
      └── README.md
      
    • Conteúdo Final de tasks/main.yml:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      
      ---
      - name: Instalar o pacote Apache
        apt:
          name: apache2
          state: present
        when: ansible_os_family == "Debian"
      
      - name: Configurar o Apache usando template
        template:
          src: apache.conf.j2
          dest: /etc/apache2/sites-available/000-default.conf
        notify: Reiniciar Apache
      
      - name: Habilitar site padrão do Apache
        command: a2ensite 000-default.conf
        notify: Reiniciar Apache
      
      - name: Iniciar e habilitar o serviço Apache
        service:
          name: apache2
          state: started
          enabled: true
      
    • Conteúdo de defaults/main.yml:

      1
      2
      3
      4
      
      ---
      apache_port: 80
      apache_server_name: "localhost"
      apache_document_root: "/var/www/html"
      

5. Criação de Templates e Uso de Arquivos em Roles

Objetivo:

Demonstrar como usar templates e arquivos em roles no Ansible para gerar arquivos de configuração dinâmicos. Isso permite que as configurações sejam adaptadas a diferentes ambientes e hosts, utilizando variáveis para personalizar as definições.

Conteúdo:

  1. Templates em Roles
    • Templates no Ansible são arquivos configuráveis que utilizam a sintaxe Jinja2 para integrar variáveis do Ansible e gerar configurações dinâmicas. Eles são especialmente úteis em roles, pois permitem que os arquivos de configuração se adaptem automaticamente aos valores definidos em variáveis.
    • Arquivos de template são armazenados no diretório templates/ de uma role e recebem a extensão .j2, indicando que são arquivos Jinja2.
  2. Criando um Template para o Arquivo de Configuração do Apache
    • Continuando com nossa role apache, vamos criar um template para o arquivo de configuração do Apache, que utiliza variáveis para definir a porta, o nome do servidor e o diretório raiz do site.
    • Conteúdo de templates/apache.conf.j2:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      <VirtualHost *:>
          ServerName 
          DocumentRoot 
      
          <Directory >
              AllowOverride All
              Require all granted
          </Directory>
      </VirtualHost>
      
    • Explicação:
      • Neste arquivo, ,, e `` são variáveis que serão substituídas pelos valores definidos em defaults/main.yml, vars/main.yml, ou pelos valores sobrescritos em um playbook ou inventário.
      • Esse template permite que a configuração do Apache seja facilmente ajustada para diferentes ambientes.
  3. Utilizando o Template em Tarefas
    • Para aplicar o template, vamos adicionar uma tarefa em tasks/main.yml que copia o template apache.conf.j2 para o diretório de configuração do Apache no servidor, substituindo o arquivo padrão.
    • Atualização de tasks/main.yml:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      
      ---
      - name: Instalar o pacote Apache
        apt:
          name: apache2
          state: present
        when: ansible_os_family == "Debian"
      
      - name: Configurar o Apache usando template
        template:
          src: apache.conf.j2
          dest: /etc/apache2/sites-available/000-default.conf
        notify: Reiniciar Apache
      
      - name: Habilitar site padrão do Apache
        command: a2ensite 000-default.conf
        notify: Reiniciar Apache
      
      - name: Iniciar e habilitar o serviço Apache
        service:
          name: apache2
          state: started
          enabled: true
      
    • Explicação:
      • A tarefa Configurar o Apache usando template usa o módulo template para copiar o arquivo apache.conf.j2 e gerar uma configuração personalizada no servidor de destino.
      • A opção notify: Reiniciar Apache chama um handler para reiniciar o Apache quando há uma alteração no arquivo de configuração.
  4. Usando Arquivos Fixos em Roles
    • Além de templates, podemos incluir arquivos fixos na role. Esses arquivos são armazenados no diretório files/ e podem ser copiados para o servidor de destino sem modificações. Isso é útil para incluir arquivos como páginas HTML, scripts de inicialização ou pacotes específicos.
    • Vamos adicionar uma página inicial padrão no diretório files/ para que seja copiada para o servidor.

    • Conteúdo de files/index.html:

      1
      2
      3
      4
      
      <html>
        <head><title>Bem-vindo ao Apache!</title></head>
        <body><h1>Esta é a página inicial do Apache!</h1></body>
      </html>
      
    • Explicação:
      • Esse arquivo será copiado diretamente para o diretório raiz definido em apache_document_root, servindo como a página inicial padrão do Apache.
  5. Copiando Arquivos Fixos com Tarefas
    • Para copiar o arquivo index.html para o servidor, vamos adicionar uma tarefa que utiliza o módulo copy em tasks/main.yml.
    • Atualização de tasks/main.yml:

      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: Instalar o pacote Apache
        apt:
          name: apache2
          state: present
        when: ansible_os_family == "Debian"
      
      - name: Configurar o Apache usando template
        template:
          src: apache.conf.j2
          dest: /etc/apache2/sites-available/000-default.conf
        notify: Reiniciar Apache
      
      - name: Habilitar site padrão do Apache
        command: a2ensite 000-default.conf
        notify: Reiniciar Apache
      
      - name: Copiar a página inicial do Apache
        copy:
          src: index.html
          dest: "/index.html"
      
      - name: Iniciar e habilitar o serviço Apache
        service:
          name: apache2
          state: started
          enabled: true
      
    • Explicação:
      • A tarefa Copiar a página inicial do Apache usa o módulo copy para copiar index.html para o diretório raiz do Apache, substituindo qualquer página inicial existente.
  6. Exemplo Completo da Role apache com Templates e Arquivos

    • Estrutura final da role apache:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      
      apache/
      ├── tasks/
      │   └── main.yml
      ├── handlers/
      │   └── main.yml
      ├── templates/
      │   └── apache.conf.j2
      ├── files/
      │   └── index.html
      ├── defaults/
      │   └── main.yml
      └── README.md
      
    • Conteúdo Final de defaults/main.yml:

      1
      2
      3
      4
      
      ---
      apache_port: 80
      apache_server_name: "localhost"
      apache_document_root: "/var/www/html"
      
  7. Testando a Role com o Template e Arquivo Fixo

    • Para testar a role com o template e o arquivo, podemos utilizar o seguinte playbook:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
      ---
      - name: Configuração de Servidor Apache com Página Inicial Customizada
        hosts: webservers
        become: true
        roles:
          - role: apache
            vars:
              apache_port: 8080
              apache_server_name: "meusite.com"
              apache_document_root: "/var/www/meusite"
      
    • Execute o playbook com:

      1
      
      ansible-playbook nome_do_playbook.yml -i inventario
      

6. Configuração de Handlers para Notificações em Roles

Objetivo:

Explicar como configurar handlers em roles para executar ações específicas após uma mudança, como reiniciar um serviço sempre que um arquivo de configuração for atualizado. Os handlers são úteis para garantir que as modificações entrem em vigor imediatamente após a aplicação.

Conteúdo:

  1. O Que São Handlers no Ansible?
    • Handlers são tarefas que são executadas apenas quando notificadas por outras tarefas. Em outras palavras, um handler só será acionado se a tarefa que o notifica realizar alguma mudança.
    • No contexto de uma role, os handlers são definidos no arquivo handlers/main.yml, garantindo que eles estejam centralizados e possam ser referenciados em toda a role.
  2. Quando Usar Handlers
    • Handlers são particularmente úteis para tarefas que precisam ser executadas apenas após uma alteração, como:
      • Reiniciar um serviço após uma mudança em seu arquivo de configuração.
      • Recarregar um sistema de firewall após a atualização de regras.
      • Executar scripts de limpeza após a modificação de diretórios temporários.
    • Ao usar handlers, você evita reiniciar ou recarregar serviços desnecessariamente, o que otimiza a execução do playbook.
  3. Criando um Handler para Reiniciar o Apache
    • Vamos criar um handler chamado Reiniciar Apache para a role apache. Esse handler será acionado sempre que o arquivo de configuração do Apache (000-default.conf) for alterado.

    • Conteúdo de handlers/main.yml:

      1
      2
      3
      4
      5
      
      ---
      - name: Reiniciar Apache
        service:
          name: apache2
          state: restarted
      
    • Explicação:

      • O handler Reiniciar Apache usa o módulo service para reiniciar o Apache. Ele será notificado por qualquer tarefa que modifique o arquivo de configuração do Apache.
  4. Notificando o Handler a Partir de uma Tarefa
    • Agora que o handler está configurado, precisamos adicionar notificações em tarefas específicas, como a tarefa que aplica o template de configuração. Quando a configuração é alterada, o handler será acionado para reiniciar o Apache.
    • Atualização de tasks/main.yml:

      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: Instalar o pacote Apache
        apt:
          name: apache2
          state: present
        when: ansible_os_family == "Debian"
      
      - name: Configurar o Apache usando template
        template:
          src: apache.conf.j2
          dest: /etc/apache2/sites-available/000-default.conf
        notify: Reiniciar Apache
      
      - name: Habilitar site padrão do Apache
        command: a2ensite 000-default.conf
        notify: Reiniciar Apache
      
      - name: Copiar a página inicial do Apache
        copy:
          src: index.html
          dest: "/index.html"
      
      - name: Iniciar e habilitar o serviço Apache
        service:
          name: apache2
          state: started
          enabled: true
      
    • Explicação:
      • As tarefas Configurar o Apache usando template e Habilitar site padrão do Apache agora notificam o handler Reiniciar Apache. Se uma dessas tarefas modificar o servidor, o handler será acionado para aplicar as mudanças imediatamente.
  5. Exemplo Completo de Role com Handlers

    • Estrutura final da role apache com handlers:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      
      apache/
      ├── tasks/
      │   └── main.yml
      ├── handlers/
      │   └── main.yml
      ├── templates/
      │   └── apache.conf.j2
      ├── files/
      │   └── index.html
      ├── defaults/
      │   └── main.yml
      └── README.md
      
  6. Testando a Role com Handlers
    • Podemos criar um playbook de teste para aplicar a role apache e verificar se o handler é acionado quando o template do Apache é atualizado.
    • Exemplo de Playbook para Teste:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
      ---
      - name: Configuração de Servidor Apache com Handler de Reinicialização
        hosts: webservers
        become: true
        roles:
          - role: apache
            vars:
              apache_port: 8080
              apache_server_name: "meusite.com"
              apache_document_root: "/var/www/meusite"
      
    • Execução do Playbook:
      1
      
      ansible-playbook nome_do_playbook.yml -i inventario
      
  7. Verificando a Execução do Handler
    • Ao rodar o playbook, observe os logs do Ansible para verificar se o handler Reiniciar Apache foi acionado após as modificações no arquivo de configuração. O Ansible notifica e executa handlers ao final do playbook, evitando reinicializações desnecessárias durante a execução.
  8. Tabela de Referência: Uso de Handlers

    Função Descrição Exemplo de Configuração
    Definir um Handler Cria o handler em handlers/main.yml service: name: apache2 state: restarted
    Notificar um Handler Adiciona notify em uma tarefa para acionar o handler notify: Reiniciar Apache
    Execução Condicional Handler é acionado apenas quando a tarefa notificada muda Handler é executado ao final do playbook

7. Uso de meta/main.yml para Dependências de Roles

Objetivo:

Demonstrar como definir dependências entre roles no Ansible usando o arquivo meta/main.yml. As dependências garantem que roles específicas sejam executadas antes de outras, permitindo configurações ordenadas e interdependentes em ambientes complexos.

Conteúdo:

  1. O Que é o Arquivo meta/main.yml?
    • O arquivo meta/main.yml define metadados da role, como informações sobre o autor, licenciamento e, especialmente, dependências de outras roles.
    • Dependências permitem que uma role especifique outras roles que precisam ser executadas previamente, assegurando que qualquer pré-requisito esteja configurado antes que a role principal seja aplicada.
    • Essa abordagem é útil em cenários onde, por exemplo, uma role de configuração de servidor web depende de uma role de firewall para liberar a porta HTTP.
  2. Definindo Dependências no meta/main.yml
    • O meta/main.yml permite listar outras roles que devem ser executadas antes da role atual. Cada dependência pode incluir variáveis próprias, específicas para a role que depende.
    • Estrutura básica de uma dependência:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
      ---
      dependencies:
        - role: firewall
          vars:
            firewall_http_port: 80
            firewall_https_port: 443
        - role: database
          vars:
            db_user: "admin"
            db_password: "senha123"
      
    • Explicação:
      • Neste exemplo, a role depende de firewall e database. Essas roles serão executadas antes da role principal. As variáveis firewall_http_port, firewall_https_port, db_user, e db_password são passadas para customizar a execução das roles dependentes.
  3. Exemplo Prático: Role webserver com Dependência de firewall
    • Suponha que temos uma role chamada webserver para configurar um servidor web. Queremos garantir que a role firewall seja executada antes, configurando o firewall para liberar as portas HTTP e HTTPS.
    • Estrutura dos diretórios:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      
      roles/
      ├── webserver/
      │   ├── tasks/
      │   │   └── main.yml
      │   ├── meta/
      │   │   └── main.yml
      │   ├── templates/
      │   │   └── apache.conf.j2
      ├── firewall/
      │   ├── tasks/
      │   │   └── main.yml
      │   └── defaults/
      │       └── main.yml
      
  4. Configurando a Role firewall
    • Para simplificar, nossa role firewall abrirá as portas necessárias para o servidor web. No arquivo firewall/tasks/main.yml, incluímos as tarefas para configurar essas portas.
    • Conteúdo de firewall/tasks/main.yml:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      
      ---
      - name: Abrir porta HTTP
        firewalld:
          port: "/tcp"
          permanent: true
          state: enabled
        when: firewall_http_port is defined
      
      - name: Abrir porta HTTPS
        firewalld:
          port: "/tcp"
          permanent: true
          state: enabled
        when: firewall_https_port is defined
      
      - name: Reload Firewall
        firewalld:
          state: reloaded
      
  5. Definindo Dependências no meta/main.yml da Role webserver
    • Agora, vamos configurar a role webserver para depender da role firewall, garantindo que o firewall esteja configurado antes do servidor web ser iniciado.
    • Conteúdo de webserver/meta/main.yml:

      1
      2
      3
      4
      5
      6
      
      ---
      dependencies:
        - role: firewall
          vars:
            firewall_http_port: 80
            firewall_https_port: 443
      
    • Explicação:
      • Esta configuração garante que a role firewall seja executada antes da role webserver. As variáveis firewall_http_port e firewall_https_port são passadas para a role firewall para abrir as portas 80 (HTTP) e 443 (HTTPS).
  6. Exemplo Completo de Configuração da Role webserver com Dependência

    • Conteúdo de webserver/tasks/main.yml:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      
      ---
      - name: Instalar o Apache
        apt:
          name: apache2
          state: present
        when: ansible_os_family == "Debian"
      
      - name: Configurar o Apache usando template
        template:
          src: apache.conf.j2
          dest: /etc/apache2/sites-available/000-default.conf
        notify: Reiniciar Apache
      
      - name: Habilitar site padrão do Apache
        command: a2ensite 000-default.conf
        notify: Reiniciar Apache
      
      - name: Iniciar e habilitar o Apache
        service:
          name: apache2
          state: started
          enabled: true
      
  7. Testando a Role webserver com Dependência
    • Para verificar se as dependências estão funcionando, crie um playbook para aplicar a role webserver. O Ansible executará automaticamente a role firewall antes de aplicar webserver, conforme definido em meta/main.yml.
    • Exemplo de Playbook:

      1
      2
      3
      4
      5
      6
      
      ---
      - name: Configuração de Servidor com Webserver e Firewall
        hosts: webservers
        become: true
        roles:
          - webserver
      
    • Execute o playbook com:
      1
      
      ansible-playbook nome_do_playbook.yml -i inventario
      
  8. Vantagens de Usar Dependências em Roles
    • Ordem de Execução: Garantir que roles sejam executadas em uma sequência lógica e ordenada, evitando erros.
    • Facilidade de Manutenção: Simplifica a estrutura dos playbooks, pois as dependências são gerenciadas diretamente nas roles.
    • Flexibilidade: Com variáveis customizáveis, as roles dependentes podem ser adaptadas para diferentes necessidades.
  9. Resumo das Dependências em meta/main.yml

    Função Descrição Exemplo de Configuração
    Definir Dependências Lista as roles que devem ser executadas antes da role atual dependencies: - role: firewall
    Personalizar com Variáveis Permite definir variáveis para roles dependentes vars: firewall_http_port: 80
    Facilita a Organização As dependências ajudam a modularizar e a organizar o fluxo de execução de playbooks complexos dependencies: - role: database

8. Incluindo Roles em Playbooks

Objetivo:

Explicar como incluir e executar roles em playbooks do Ansible, aproveitando as vantagens da modularização para organizar e aplicar configurações complexas de forma eficiente.

Conteúdo:

  1. Usando a Diretiva roles em Playbooks
    • A maneira mais comum de incluir roles em um playbook é através da diretiva roles. Em vez de definir tarefas diretamente no playbook, você pode listar as roles a serem executadas. Isso torna o playbook mais limpo e fácil de entender.
    • Estrutura básica:

      1
      2
      3
      4
      5
      6
      7
      
      ---
      - name: Playbook de Configuração
        hosts: all
        become: true
        roles:
          - nome_da_role1
          - nome_da_role2
      
    • Explicação:
      • Cada role especificada na lista roles é executada em sequência nos hosts definidos, aplicando suas configurações.
  2. Exemplo Prático de Playbook com Roles
    • Vamos criar um playbook que configura um servidor completo utilizando três roles: firewall, webserver, e database.
    • Estrutura de Diretórios:
      1
      2
      3
      4
      5
      6
      
      project/
      ├── playbook.yml
      └── roles/
          ├── firewall/
          ├── webserver/
          └── database/
      
    • Conteúdo de playbook.yml:

      1
      2
      3
      4
      5
      6
      7
      8
      
      ---
      - name: Configuração Completa do Servidor
        hosts: servers
        become: true
        roles:
          - firewall
          - webserver
          - database
      
    • Explicação:
      • Esse playbook aplica, em sequência, as roles firewall, webserver e database para todos os hosts no grupo servers. Cada role configura uma parte do ambiente de servidor, tornando o playbook modular e fácil de expandir.
  3. Execução de Múltiplas Roles em um Único Playbook
    • No Ansible, as roles são executadas na ordem em que são listadas no playbook. Roles com dependências (definidas no meta/main.yml) são automaticamente aplicadas antes da role principal.
    • Exemplo:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      ---
      - name: Configuração do Servidor com Dependências
        hosts: webservers
        become: true
        roles:
          - firewall
          - role: webserver
            vars:
              apache_port: 8080
              apache_server_name: "meusite.com"
          - database
      
    • Explicação:
      • Aqui, o playbook executa firewall, depois webserver (com variáveis específicas para esse servidor), e finalmente database. Essa estrutura é útil para aplicar configurações detalhadas e organizadas em servidores complexos.
  4. Personalizando Roles em Playbooks com Variáveis
    • Roles podem ser personalizadas diretamente no playbook usando variáveis específicas. Isso é feito dentro da definição da role, aplicando variáveis de forma customizada para cada play.
    • Exemplo com Variáveis:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      ---
      - name: Configurar Webserver com Variáveis Customizadas
        hosts: webservers
        become: true
        roles:
          - role: webserver
            vars:
              apache_port: 8080
              apache_server_name: "customsite.com"
      
    • Explicação:
      • As variáveis apache_port e apache_server_name sobrescrevem os valores padrão definidos na role webserver, permitindo personalizar a configuração para este play específico.
  5. Usando Condicionais para Executar Roles com when
    • Em cenários onde você quer aplicar uma role apenas em condições específicas, pode-se usar when para definir essa execução condicional.
    • Exemplo:

      1
      2
      3
      4
      5
      6
      7
      
      ---
      - name: Configuração Condicional de Firewall e Webserver
        hosts: all
        become: true
        roles:
          - { role: firewall, when: ansible_os_family == "RedHat" }
          - { role: webserver, when: ansible_os_family == "Debian" }
      
    • Explicação:
      • A role firewall será executada apenas se o sistema operacional for da família RedHat, enquanto a role webserver será aplicada apenas em sistemas Debian. Isso é útil para aplicar roles com base no tipo de sistema operacional ou outras condições.
  6. Passagem de Variáveis a Múltiplas Roles no Playbook
    • Quando um playbook inclui várias roles que precisam das mesmas variáveis, é possível definir essas variáveis no nível do play, aplicando-as a todas as roles que as utilizarem.
    • Exemplo:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      
      ---
      - name: Configuração Completa com Variáveis Globais
        hosts: servers
        become: true
        vars:
          apache_port: 80
          db_user: "admin"
          db_password: "senha123"
        roles:
          - firewall
          - webserver
          - database
      
    • Explicação:
      • Nesse exemplo, apache_port, db_user e db_password são variáveis globais, acessíveis a todas as roles no play (firewall, webserver, e database). Isso simplifica a passagem de variáveis compartilhadas.
  7. Exemplo Completo de Playbook com Múltiplas Roles

    • Conteúdo Final do Playbook Completo:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      
      ---
      - name: Configuração de Infraestrutura Completa
        hosts: servers
        become: true
        vars:
          apache_port: 8080
          apache_server_name: "intranet.local"
          db_user: "admin"
          db_password: "securepassword"
        roles:
          - firewall
          - role: webserver
            vars:
              apache_document_root: "/var/www/intranet"
          - database
      
    • Explicação:

      • Esse playbook configura uma infraestrutura completa, aplicando firewall, webserver, e database. A role webserver é customizada para usar uma porta específica, um servidor específico, e um diretório raiz diferente. A flexibilidade do Ansible permite que múltiplas roles compartilhem variáveis globais ou usem variáveis específicas, conforme necessário.
  8. Vantagens de Usar Roles em Playbooks

    Vantagem Descrição
    Modularização Facilita a leitura e manutenção de configurações complexas, agrupando funcionalidades em roles.
    Reutilização Permite que uma role seja usada em diferentes playbooks e ambientes com mínima adaptação.
    Flexibilidade Roles podem ser configuradas com variáveis globais ou customizadas para hosts e grupos específicos.
    Execução Condicional Possibilidade de definir condições para execução de roles, permitindo um controle avançado.

9. Personalização de Roles com Variáveis em Playbooks

Objetivo:

Demonstrar como sobrescrever variáveis de roles em playbooks para adaptar as configurações a diferentes ambientes, hosts ou grupos, sem modificar a estrutura interna das roles.

Conteúdo:

  1. Por Que Sobrescrever Variáveis de Roles?
    • Roles geralmente incluem variáveis padrão em defaults/main.yml, permitindo uma configuração básica que pode ser usada em diversos ambientes. No entanto, ao usar uma role em diferentes contextos, é comum que seja necessário alterar essas variáveis para ajustar a configuração de acordo com o ambiente (produção, teste, etc.) ou as especificidades dos hosts.
    • Sobrescrever variáveis diretamente no playbook permite que você adapte a configuração sem modificar o código da role, mantendo-a reutilizável e independente.
  2. Métodos de Sobrescrever Variáveis de Roles
    • Existem diversas maneiras de sobrescrever variáveis de roles:
      • Definindo-as diretamente no playbook, dentro da definição de cada role.
      • Utilizando variáveis no nível do play, para que todas as roles compartilhem as mesmas variáveis.
      • Configurando variáveis no inventário, permitindo que diferentes hosts ou grupos recebam valores específicos.
  3. Exemplo de Sobrescrição de Variáveis no Playbook
    • No playbook, você pode sobrescrever variáveis específicas ao listar cada role. Essa abordagem permite aplicar configurações diferentes para cada execução, sem modificar o código da role.
    • Exemplo:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      
      ---
      - name: Configuração Personalizada do Servidor Web
        hosts: webservers
        become: true
        roles:
          - role: webserver
            vars:
              apache_port: 8080
              apache_server_name: "intranet.local"
              apache_document_root: "/var/www/intranet"
      
    • Explicação:
      • Neste exemplo, as variáveis apache_port, apache_server_name, e apache_document_root são configuradas especificamente para essa execução da role webserver, permitindo a personalização da configuração do Apache.
  4. Definindo Variáveis no Nível do Play
    • Quando várias roles utilizam as mesmas variáveis, é possível defini-las no nível do play, o que torna as variáveis globais para todas as roles listadas.
    • Exemplo:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      ---
      - name: Configuração Completa do Servidor
        hosts: all
        become: true
        vars:
          db_user: "admin"
          db_password: "securepassword"
        roles:
          - firewall
          - webserver
          - database
      
    • Explicação:
      • Nesse caso, as variáveis db_user e db_password são definidas para serem acessíveis em todas as roles do play, permitindo que database use essas variáveis diretamente, sem precisar sobrescrevê-las para cada role.
  5. Sobrescrevendo Variáveis no Inventário
    • Quando você precisa personalizar uma role para diferentes hosts ou grupos, pode definir variáveis diretamente no inventário, adaptando a configuração conforme o host.
    • Exemplo de Inventário:
      1
      2
      3
      
      [webservers]
      servidor1 apache_port=8081 apache_server_name=servidor1.intranet.local
      servidor2 apache_port=8082 apache_server_name=servidor2.intranet.local
      
    • Explicação:
      • Neste exemplo, o host servidor1 executa o Apache na porta 8081 com o nome servidor1.intranet.local, enquanto servidor2 usa a porta 8082 e o nome servidor2.intranet.local. Essas variáveis específicas de host permitem uma configuração detalhada sem modificar a role.
  6. Exemplo Completo com Diferentes Métodos de Personalização

    • Playbook Completo:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      
      ---
      - name: Configuração de Servidor com Customização Completa
        hosts: all
        become: true
        vars:
          db_user: "root"
          db_password: "rootpassword"
        roles:
          - firewall
          - role: webserver
            vars:
              apache_port: 8080
              apache_server_name: "central.intranet"
              apache_document_root: "/var/www/central"
          - role: database
      
    • Inventário:
      1
      2
      3
      
      [webservers]
      servidor1 apache_port=8081 apache_server_name=servidor1.intranet.local
      servidor2 apache_port=8082 apache_server_name=servidor2.intranet.local
      
    • Explicação:
      • Neste exemplo, o playbook define variáveis de database no nível do play, enquanto as variáveis apache_port e apache_server_name para a role webserver são definidas no playbook para o servidor central e no inventário para os demais servidores web. Isso permite que cada servidor seja configurado com valores específicos, criando uma infraestrutura sob medida.
  7. Tabela de Referência: Métodos de Sobrescrever Variáveis

    Método Descrição Exemplo
    Definindo no Playbook Variáveis específicas para a role são configuradas diretamente no playbook - role: webserver vars: apache_port: 8080
    Variáveis no Play Variáveis são aplicadas globalmente para todas as roles do play vars: db_user: "admin"
    Variáveis no Inventário Variáveis são configuradas por host ou grupo, personalizando cada servidor conforme necessário servidor1 apache_port=8081 apache_server_name=...
  8. Boas Práticas para Personalização de Roles
    • Use defaults para Variáveis Padrão: Defina valores padrão em defaults/main.yml para que a role seja funcional sem necessidade de customização imediata.
    • Personalize no Inventário para Configurações por Host: Ao personalizar para diferentes hosts, defina variáveis no inventário para facilitar a administração e evitar duplicação de código no playbook.
    • Sobrescreva no Playbook para Customizações Únicas: Se a personalização for específica para uma execução, defina variáveis diretamente no playbook, mantendo a flexibilidade de acordo com o contexto.

10. Organização e Estruturação de Projetos com Múltiplas Roles

Objetivo:

Explicar como organizar projetos Ansible que envolvem múltiplas roles, incluindo a estrutura de diretórios e práticas recomendadas para modularidade e reusabilidade. Projetos bem organizados facilitam a manutenção e a escalabilidade em ambientes complexos.

Conteúdo:

  1. Estrutura Básica para Projetos com Múltiplas Roles
    • Em projetos Ansible que utilizam várias roles, uma estrutura de diretórios clara e modular permite que cada parte da configuração seja isolada, reutilizável e fácil de gerenciar.
    • Exemplo de estrutura para um projeto com múltiplas roles:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      
      project_name/
      ├── playbooks/
      │   ├── site.yml
      │   ├── webserver.yml
      │   └── database.yml
      ├── roles/
      │   ├── firewall/
      │   ├── webserver/
      │   └── database/
      ├── inventories/
      │   ├── production
      │   │   ├── hosts
      │   │   └── group_vars/
      │   │       └── all.yml
      │   └── staging
      │       ├── hosts
      │       └── group_vars/
      │           └── all.yml
      └── ansible.cfg
      
  2. Organização de Playbooks
    • Em projetos com múltiplas roles, é útil ter playbooks distintos para cada camada ou grupo de serviços (por exemplo, webserver.yml para servidores web e database.yml para bancos de dados).
    • Conteúdo de site.yml (Playbook principal que chama outros playbooks):

      1
      2
      3
      4
      
      ---
      - import_playbook: webserver.yml
      - import_playbook: database.yml
      - import_playbook: firewall.yml
      
    • Explicação:
      • site.yml atua como o ponto central para configurar a infraestrutura completa, importando playbooks menores e específicos. Essa abordagem modulariza ainda mais o projeto.
  3. Estrutura de Inventários para Ambientes Separados
    • Manter inventários separados para ambientes como production e staging permite que a mesma estrutura de roles e playbooks seja usada em diferentes ambientes com configurações distintas.
    • Exemplo de diretório inventories/:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      inventories/
      ├── production/
      │   ├── hosts
      │   └── group_vars/
      │       └── all.yml
      └── staging/
          ├── hosts
          └── group_vars/
              └── all.yml
      
    • Inventário de Produção (inventories/production/hosts):
      1
      2
      3
      4
      5
      6
      
      [webservers]
      server1 ansible_host=192.168.1.10
      server2 ansible_host=192.168.1.11
      
      [databases]
      db1 ansible_host=192.168.1.20
      
    • Explicação:
      • Cada ambiente tem seu próprio inventário e variáveis específicas no diretório group_vars, permitindo configurações sob medida para produção, teste e desenvolvimento.
  4. Organização de group_vars e host_vars
    • group_vars/: Define variáveis para grupos de hosts, aplicando configurações específicas de grupo (como webservers ou databases).
    • host_vars/: Define variáveis específicas para hosts individuais, permitindo configurações detalhadas para hosts únicos.
    • Exemplo:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      
      inventories/
      └── production/
          ├── group_vars/
          │   ├── all.yml
          │   ├── webservers.yml
          │   └── databases.yml
          └── host_vars/
              ├── server1.yml
              └── db1.yml
      
  5. Definindo ansible.cfg para Configuração do Projeto
    • O arquivo ansible.cfg é uma configuração local que pode ser usada para definir padrões específicos para o projeto, como o diretório de inventário e o caminho para roles.
    • Conteúdo de ansible.cfg:
      1
      2
      3
      4
      5
      
      [defaults]
      inventory = inventories/production/hosts
      roles_path = roles/
      host_key_checking = False
      retry_files_enabled = False
      
    • Explicação:
      • O inventory define o inventário padrão (pode ser alterado com staging/hosts para testes).
      • roles_path indica onde o Ansible buscará roles, e host_key_checking evita a verificação de chaves SSH ao conectar-se a novos hosts.
  6. Exemplo Completo de Playbook e Inventário
    • Playbook webserver.yml:

      1
      2
      3
      4
      5
      6
      7
      
      ---
      - name: Configuração de Servidor Web
        hosts: webservers
        become: true
        roles:
          - firewall
          - webserver
      
    • Playbook database.yml:

      1
      2
      3
      4
      5
      6
      
      ---
      - name: Configuração do Banco de Dados
        hosts: databases
        become: true
        roles:
          - database
      
    • Variáveis para webservers (inventories/production/group_vars/webservers.yml):

      1
      2
      
      apache_port: 8080
      apache_server_name: "production.intranet.local"
      
  7. Boas Práticas de Organização com Múltiplas Roles

    Prática Descrição
    Modularização de Playbooks Divida playbooks para cada função ou grupo de serviços para facilitar manutenção e execução controlada.
    Inventários Separados Use inventários separados para diferentes ambientes, como produção e staging, para evitar erros acidentais.
    Variáveis Centralizadas Utilize group_vars e host_vars para centralizar variáveis e evitar repetição em playbooks.
    Ansible Config Local Use ansible.cfg para definir diretórios de roles e inventários de forma centralizada e específica do projeto.
  8. Vantagens da Estruturação Modular

    • Facilidade de Escalabilidade: À medida que o projeto cresce, a estrutura modular facilita a adição de novos serviços e ajustes em roles específicas.
    • Manutenção Simplificada: Cada parte da configuração é isolada, facilitando a atualização e a correção de configurações sem impactar outros serviços.
    • Redução de Erros: A separação de ambientes em inventários distintos reduz o risco de execução acidental em produção.
    • Reutilização e Padronização: Roles e playbooks modulares são mais fáceis de reaproveitar e padronizar em diferentes projetos.

11. Boas Práticas para Criação e Manutenção de Roles

Objetivo:

Fornecer um checklist de boas práticas para o desenvolvimento e manutenção de roles no Ansible. Essas práticas ajudam a criar roles consistentes, reutilizáveis e fáceis de manter, especialmente em projetos colaborativos e ambientes de produção.

Conteúdo:

  1. Organização e Estrutura Consistente
    • Mantenha a Estrutura Padrão de Roles: A estrutura padrão de roles no Ansible (com diretórios como tasks/, handlers/, templates/, etc.) facilita a leitura e o entendimento do projeto, especialmente para novos membros da equipe.
    • Utilize o Comando ansible-galaxy init para Criar Roles: Este comando gera a estrutura de pastas correta, garantindo que cada role tenha os arquivos e diretórios esperados desde o início.
    • Separe Lógica em Arquivos: Quando uma role se torna extensa, divida tarefas em arquivos menores usando import_tasks ou include_tasks. Isso facilita o debug e a manutenção.
  2. Uso Eficiente de Variáveis
    • Defina Variáveis Padrão em defaults/main.yml: Variáveis padrão devem ser definidas em defaults/, facilitando a sobrescrição quando necessário. Isso aumenta a flexibilidade da role.
    • Evite Variáveis Fixas no Código: Sempre que possível, evite valores fixos diretamente nas tarefas; use variáveis para tornar a role mais reutilizável e adaptável.
    • Documente as Variáveis em README.md: Inclua uma lista de variáveis no arquivo README.md da role, com descrições e valores padrão. Isso facilita a compreensão e o uso da role por outras pessoas.
  3. Modularização de Tarefas e Handlers
    • Centralize Handlers em handlers/main.yml: Defina todos os handlers em um único arquivo para facilitar o gerenciamento. Cada tarefa que requer um handler deve notificar apenas se houver mudanças, evitando reinicializações desnecessárias.
    • Modularize Tarefas Repetitivas: Se uma role contém tarefas repetitivas, mova-as para arquivos separados e use import_tasks para incluí-las. Isso simplifica a manutenção e evita redundância.
  4. Documentação e Descrição
    • Use o Campo name em Todas as Tarefas: Cada tarefa deve ter um nome descritivo para facilitar a identificação no log de execução. Isso é crucial para debugging e para entender o que cada etapa faz.
    • Documente a Role no README.md: Inclua descrições das funcionalidades, variáveis e exemplos de uso. Isso é útil tanto para quem usa quanto para quem mantém a role.
    • Adicione Comentários para Lógica Complexa: Quando houver tarefas ou condicionais complexas, adicione comentários explicando o propósito. Isso ajuda na manutenção e revisão.
  5. Segurança e Ansible Vault
    • Criptografe Variáveis Sensíveis com Ansible Vault: Evite expor senhas, chaves e outras informações sensíveis. Use o Ansible Vault para criptografar variáveis sensíveis antes de armazená-las em inventários ou arquivos de variáveis.
      1
      
      ansible-vault encrypt group_vars/production.yml
      
    • Evite Variáveis Sensíveis no Código das Roles: Nunca insira informações sensíveis diretamente nas roles. Isso melhora a segurança e facilita a auditoria das configurações.
  6. Testes e Modo de Simulação
    • Use --check para Testes Sem Aplicação: O modo --check executa o playbook em “modo de simulação”, exibindo as alterações que seriam feitas sem aplicá-las de fato.
      1
      
      ansible-playbook site.yml --check
      
    • Verifique Diferenças em Arquivos com --diff: O parâmetro --diff mostra as diferenças entre o estado atual e o desejado em arquivos de configuração. Isso é útil para revisar mudanças antes de aplicá-las.
      1
      
      ansible-playbook site.yml --check --diff
      
    • Testes de Roles Isolados: Sempre que possível, teste cada role de forma isolada antes de incluí-la em playbooks maiores. Isso facilita o debug e ajuda a identificar problemas específicos.
  7. Controle de Versão e Atualizações
    • Versione Roles em um Repositório Git: Armazene cada role em um repositório separado ou versionado dentro do projeto principal. Isso permite acompanhar mudanças e reverter atualizações quando necessário.
    • Use Tags para Marcar Versões Estáveis: Quando uma role atinge um estado estável, marque-a com uma tag no Git. Isso facilita o gerenciamento de versões em ambientes de produção.
    • Revisão e Atualização Periódica de Roles: Roles devem ser revisadas periodicamente para manter compatibilidade com novas versões de pacotes e sistemas operacionais, especialmente em produção.
  8. Checklist de Boas Práticas para Manutenção de Roles

    Boas Práticas Descrição
    Estrutura Padrão Utilize ansible-galaxy init para garantir a estrutura correta e modularidade desde o início.
    Uso de Variáveis Defina variáveis padrão em defaults/ e evite valores fixos no código das tarefas.
    Centralização de Handlers Coloque todos os handlers em handlers/main.yml e notifique apenas quando necessário para otimizar o processo.
    Documentação Clara Documente cada variável e tarefa; use README.md para descrever o propósito e os parâmetros da role.
    Segurança com Vault Criptografe variáveis sensíveis com Ansible Vault e evite expô-las no código ou inventários.
    Testes e Simulações Use --check e --diff para validar alterações antes de aplicá-las em produção.
    Controle de Versão Versione roles no Git e utilize tags para gerenciar versões estáveis para produção.

12. Uso do Ansible Galaxy para Download e Compartilhamento de Roles

Objetivo:

Explicar como utilizar o Ansible Galaxy para baixar e compartilhar roles, aproveitando a ampla biblioteca de roles desenvolvidas pela comunidade e permitindo que você publique suas próprias roles para outros usuários.

Conteúdo:

  1. O Que é o Ansible Galaxy?
    • O Ansible Galaxy é um repositório de roles compartilhado pela comunidade, onde usuários podem baixar e publicar roles de automação. Ele facilita o acesso a roles prontas para diversos serviços e aplicações, economizando tempo na configuração de playbooks.
    • Além de usar roles criadas por outros, você também pode publicar suas próprias roles para compartilhar configurações padronizadas com a comunidade ou dentro de sua própria organização.
  2. Baixando Roles do Ansible Galaxy
    • Para buscar e instalar roles, o Ansible Galaxy fornece o comando ansible-galaxy install, que baixa roles do repositório diretamente para o seu projeto.
    • Instalação de Uma Role do Galaxy:
      1
      
      ansible-galaxy install nome_do_usuario.nome_da_role
      
    • Exemplo:
      1
      
      ansible-galaxy install geerlingguy.apache
      
    • Explicação:
      • Esse comando instala a role apache, desenvolvida pelo usuário geerlingguy, e a armazena em um diretório padrão (geralmente ~/.ansible/roles/ ou roles/ se configurado em ansible.cfg).
  3. Especificando Versões de Roles ao Baixar
    • O Ansible Galaxy permite instalar versões específicas de uma role. Isso é útil para garantir que a role seja compatível com a sua configuração atual.
    • Instalação de Uma Role com Versão Específica:
      1
      
      ansible-galaxy install nome_do_usuario.nome_da_role,1.0.0
      
    • Exemplo:
      1
      
      ansible-galaxy install geerlingguy.apache,3.2.0
      
  4. Gerenciamento de Roles no Arquivo requirements.yml
    • Para projetos que utilizam múltiplas roles do Ansible Galaxy, o arquivo requirements.yml permite listar todas as roles necessárias, com suas respectivas versões. Esse arquivo simplifica o gerenciamento e facilita a instalação de todas as dependências com um único comando.
    • Conteúdo de requirements.yml:

      1
      2
      3
      4
      5
      6
      7
      
      ---
      - src: geerlingguy.apache
        version: 3.2.0
      - src: geerlingguy.mysql
        version: 2.9.1
      - src: community.general
        version: 1.3.0
      
    • Instalação de Todas as Roles Listadas em requirements.yml:
      1
      
      ansible-galaxy install -r requirements.yml
      
    • Explicação:
      • O comando instala todas as roles e versões listadas no arquivo requirements.yml, garantindo que o projeto seja configurado com as dependências corretas.
  5. Publicando Roles no Ansible Galaxy
    • Para compartilhar suas roles no Ansible Galaxy, você precisa publicá-las em um repositório Git, como GitHub ou GitLab, e conectar o repositório à sua conta no Galaxy.
    • Passos para Publicar uma Role:
      1. Organize a Role: Certifique-se de que a role segue a estrutura padrão do Ansible e possui um README.md com a documentação necessária.
      2. Versionamento: Use o Git para criar uma tag no repositório, indicando a versão da role.
      3. Login no Galaxy: Faça login na sua conta do Ansible Galaxy.
      4. Importação da Role: No Ansible Galaxy, adicione o repositório Git da role e inicie o processo de importação.
    • Exemplo de Publicação com Git:
      1
      2
      
      git tag 1.0.0
      git push origin --tags
      
    • No Ansible Galaxy, você pode então importar a role a partir do repositório e ela ficará disponível publicamente.
  6. Checklist para Publicação de Roles no Galaxy

    Tarefa Descrição
    Estrutura Padrão Confirme que a role segue a estrutura padrão do Ansible para garantir compatibilidade.
    Documentação Completa O README.md deve incluir instruções de uso, variáveis e exemplos para facilitar a adoção.
    Versionamento com Git Use tags para indicar versões estáveis, facilitando a escolha da versão no Galaxy.
    Testes Antes da Publicação Execute testes com --check e --diff para garantir que a role funcione conforme esperado.
    Dependências no meta/main.yml Defina dependências de outras roles, se necessário, no arquivo meta/main.yml.
  7. Exemplo Completo: Utilizando uma Role do Galaxy no Playbook

    • Criação de um Arquivo requirements.yml:

      1
      2
      3
      4
      5
      
      ---
      - src: geerlingguy.apache
        version: 3.2.0
      - src: geerlingguy.mysql
        version: 2.9.1
      
    • Instalação das Roles:
      1
      
      ansible-galaxy install -r requirements.yml
      
    • Playbook que Usa as Roles do Galaxy:

      1
      2
      3
      4
      5
      6
      7
      
      ---
      - name: Configuração Completa com Apache e MySQL
        hosts: webservers
        become: true
        roles:
          - geerlingguy.apache
          - geerlingguy.mysql
      
  8. Vantagens do Uso do Ansible Galaxy
    • Reutilização de Código: O Galaxy permite o uso de roles de alta qualidade desenvolvidas por especialistas, economizando tempo de desenvolvimento.
    • Padronização e Qualidade: Muitas roles no Galaxy são amplamente testadas e atualizadas pela comunidade, oferecendo soluções confiáveis para configurações complexas.
    • Facilidade de Compartilhamento: Publicar roles no Galaxy permite compartilhar configurações padronizadas com sua equipe ou com a comunidade, promovendo a colaboração e a consistência.

Conclusão

Este tutorial completo sobre roles no Ansible fornece uma base sólida para implementar, organizar e compartilhar configurações robustas de infraestrutura. Ao adotar uma abordagem modular e reusável, você consegue gerenciar configurações complexas com facilidade, aplicando práticas que garantem a consistência e escalabilidade do seu ambiente.

As roles no Ansible não apenas economizam tempo e reduzem erros, mas também promovem um padrão de configuração flexível e adaptável a diferentes cenários. O uso do Ansible Galaxy para compartilhar e baixar roles de terceiros permite que você aproveite a experiência da comunidade, integrando rapidamente configurações testadas e comprovadas.

Com essas práticas, você está pronto para construir uma infraestrutura altamente automatizada e colaborativa, que atende tanto às necessidades de produção quanto aos requisitos de segurança e qualidade. Que este tutorial seja um recurso valioso em sua jornada para aprimorar a eficiência e padronização da sua automação com o Ansible.


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