Montar e Executar um Playbook com Roles Personalizadas, Git e de Sistema
Nesta etapa, você reunirá todos os componentes que preparou: sua role personalizada, a dependência do Git e a RHEL System Role. Você criará um playbook principal que orquestra essas roles para configurar completamente o servidor web de desenvolvimento.
Pense nesta etapa como a montagem de uma máquina complexa a partir de diferentes peças - cada role serve a um propósito específico e elas trabalham juntas para criar um ambiente completo de servidor web. Vamos detalhar isso em partes gerenciáveis:
Primeiro, certifique-se de estar no diretório principal do projeto.
cd ~/project
Antes de mergulhar na configuração, vamos entender o que estamos criando:
- Configuração do Ansible: Configura como o Ansible se comporta e onde encontra os arquivos
- Inventário: Define quais servidores gerenciar (no nosso caso, localhost)
- Variáveis: Armazenam dados que nossas roles usarão (informações do desenvolvedor, configurações do SELinux)
- Conteúdo da Role Personalizada: As tarefas reais que configurarão os ambientes de desenvolvimento
- Playbook Principal: O orquestrador que executa tudo na ordem correta
1. Criar Configuração e Inventário do Ansible
O arquivo ansible.cfg é como um arquivo de configuração que diz ao Ansible como se comportar. Sem ele, você precisaria especificar caminhos e opções em cada comando. Com ele, o Ansible sabe automaticamente onde encontrar suas roles, coleções e inventário.
Crie o arquivo ansible.cfg usando nano. Este arquivo diz ao Ansible onde encontrar suas roles, coleções e inventário.
nano ansible.cfg
Adicione o seguinte conteúdo. Vamos entender cada linha:
[defaults]
inventory = inventory
roles_path = roles
collections_paths = collections
host_key_checking = False
[privilege_escalation]
become = True
O que cada configuração faz:
inventory = inventory: Em vez de digitar -i inventory toda vez, o Ansible usará automaticamente este arquivo
roles_path = roles: O Ansible procurará roles no diretório roles
collections_paths = collections: O Ansible encontrará suas coleções instaladas aqui
host_key_checking = False: Impede erros de verificação de chave SSH em ambientes de laboratório
become = True: Executa automaticamente tarefas com privilégios elevados quando necessário
Salve e saia do nano (Pressione Ctrl+X, depois Y, depois Enter).
O arquivo de inventário diz ao Ansible quais máquinas gerenciar. No nosso caso, estamos configurando a máquina local.
nano inventory
Adicione a seguinte linha:
localhost ansible_connection=local
O que isso significa:
localhost: O nome do nosso host de destino
ansible_connection=local: Em vez de SSH, use conexões locais (já que estamos gerenciando a mesma máquina em que estamos executando o Ansible)
Salve e saia do nano.
2. Definir Variáveis de Role
Variáveis no Ansible são como configurações que suas roles podem usar. Em vez de codificar valores como nomes de usuário ou números de porta em suas tarefas, você os define em arquivos de variáveis. Isso torna sua automação flexível e reutilizável.
O diretório group_vars/all é um local especial onde o Ansible carrega automaticamente variáveis para todos os hosts. Qualquer arquivo YAML neste diretório fica disponível para seus playbooks e roles.
Crie a estrutura de diretórios para variáveis que se aplicam a todos os hosts:
mkdir -p group_vars/all
Agora, crie um arquivo para definir as informações do desenvolvedor. Esses dados serão usados por sua role personalizada para criar contas de usuário e configurações web.
nano group_vars/all/developers.yml
Adicione o seguinte conteúdo:
---
web_developers:
- username: jdoe ## Primeiro desenvolvedor
port: 9081 ## Porta personalizada para o site deste desenvolvedor
- username: jdoe2 ## Segundo desenvolvedor
port: 9082 ## Porta personalizada para o site deste desenvolvedor
O que esta estrutura de dados significa:
web_developers: Uma lista contendo informações do desenvolvedor
- Cada desenvolvedor tem um
username e uma port
- Sua role personalizada percorrerá esta lista para criar configurações para cada desenvolvedor
Salve e saia.
Em seguida, crie um arquivo de variáveis para a configuração do SELinux. SELinux (Security-Enhanced Linux) é um módulo de segurança que controla o que os aplicativos podem fazer.
nano group_vars/all/selinux.yml
Adicione o seguinte conteúdo:
---
selinux_state: enforcing ## Define o SELinux para o modo enforcing (maior segurança)
selinux_ports: ## Lista de portas para permitir que o Apache use
- ports: "9081" ## Permite a porta 9081
proto: "tcp" ## Protocolo: TCP
setype: "http_port_t" ## Tipo SELinux: porta HTTP
state: "present" ## Adiciona esta regra
- ports: "9082" ## Permite a porta 9082
proto: "tcp" ## Protocolo: TCP
setype: "http_port_t" ## Tipo SELinux: porta HTTP
state: "present" ## Adiciona esta regra
Entendendo as configurações do SELinux:
selinux_state: enforcing: O SELinux bloqueará ativamente ações não autorizadas
selinux_ports: Uma lista de configurações de porta
http_port_t: O tipo SELinux que permite ao Apache vincular-se a portas
- Por padrão, o Apache só pode usar as portas 80 e 443; precisamos permitir explicitamente 9081 e 9082
Salve e saia.
3. Popular a Role Personalizada
Sua role apache.developer_configs atualmente tem a estrutura de diretórios, mas nenhum conteúdo real. Precisamos adicionar:
- Templates: Arquivos que podem incluir variáveis (usando sintaxe Jinja2)
- Tarefas: O trabalho real que o Ansible realizará
- Handlers: Tarefas especiais que só são executadas quando notificadas (como reiniciar serviços)
- Metadados: Informações sobre dependências de roles
Templates permitem que você crie arquivos de configuração que se adaptam com base em suas variáveis. A extensão .j2 indica que este é um template Jinja2.
nano roles/apache.developer_configs/templates/developer.conf.j2
Adicione o seguinte conteúdo:
{% for dev in web_developers %}
Listen {{ dev.port }}
<VirtualHost *:{{ dev.port }}>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/{{ dev.username }}
<Directory /var/www/{{ dev.username }}>
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
</VirtualHost>
{% endfor %}
Entendendo a sintaxe do template:
{% for dev in web_developers %}: Inicia um loop pela lista de desenvolvedores
{{ dev.port }}: Insere o número da porta para este desenvolvedor
{{ dev.username }}: Insere o nome de usuário para este desenvolvedor
{% endfor %}: Finaliza o loop
- O resultado serão configurações de virtual host separadas para cada desenvolvedor
O que isso cria: Para nossos dois desenvolvedores, este template gerará a configuração do Apache que:
- Faz o Apache escutar nas portas 9081 e 9082
- Cria virtual hosts que servem conteúdo de
/var/www/jdoe e /var/www/jdoe2
- Define permissões apropriadas para cada diretório
Salve e saia.
Tarefas são o trabalho real que o Ansible realiza. Cada tarefa usa um módulo Ansible para realizar algo específico.
nano roles/apache.developer_configs/tasks/main.yml
Adicione o seguinte conteúdo e vamos entender cada tarefa:
---
## Tarefa 1: Criar contas de usuário para cada desenvolvedor
- name: Create developer user accounts
ansible.builtin.user: ## Usa o módulo 'user'
name: "{{ item.username }}" ## Cria o usuário com este nome
state: present ## Garante que o usuário exista
loop: "{{ web_developers }}" ## Faz isso para cada desenvolvedor na lista
## Tarefa 2: Criar diretórios web para cada desenvolvedor
- name: Create developer web root directories
ansible.builtin.file: ## Usa o módulo 'file'
path: "/var/www/{{ item.username }}" ## Cria este diretório
state: directory ## Garante que seja um diretório
owner: "{{ item.username }}" ## Define o proprietário
group: "{{ item.username }}" ## Define o grupo
mode: "0755" ## Define as permissões (rwxr-xr-x)
loop: "{{ web_developers }}"
## Tarefa 3: Criar uma página de exemplo index.html para cada desenvolvedor
- name: Create a sample index.html for each developer
ansible.builtin.copy: ## Usa o módulo 'copy'
content: "Welcome to {{ item.username }}'s dev space\n" ## Conteúdo do arquivo
dest: "/var/www/{{ item.username }}/index.html" ## Onde colocar o arquivo
owner: "{{ item.username }}" ## Proprietário do arquivo
group: "{{ item.username }}" ## Grupo do arquivo
mode: "0644" ## Permissões do arquivo (rw-r--r--)
loop: "{{ web_developers }}"
## Tarefa 4: Implantar o arquivo de configuração do Apache
- name: Deploy developer apache configs
ansible.builtin.template: ## Usa o módulo 'template'
src: developer.conf.j2 ## Arquivo de template de origem
dest: /etc/httpd/conf.d/developer.conf ## Destino no servidor
mode: "0644" ## Permissões do arquivo
notify: restart apache ## Aciona o handler de reinício quando isso mudar
Entendendo os conceitos chave:
loop: Repete a tarefa para cada item na lista
{{ item.username }}: Refere-se ao nome de usuário do item atual no loop
notify: restart apache: Quando esta tarefa fizer alterações, ela acionará um handler chamado "restart apache"
- Permissões de arquivo:
0755 significa que o proprietário pode ler/escrever/executar, outros podem ler/executar; 0644 significa que o proprietário pode ler/escrever, outros podem apenas ler
Salve e saia.
Handlers são tarefas especiais que só são executadas quando notificadas por outras tarefas. Eles são tipicamente usados para ações como reiniciar serviços.
nano roles/apache.developer_configs/handlers/main.yml
Adicione o seguinte conteúdo:
---
- name: restart apache ## Este nome deve corresponder à declaração notify:
ansible.builtin.service: ## Usa o módulo 'service'
name: httpd ## O nome do serviço (Apache é chamado 'httpd' no RHEL)
state: restarted ## Reinicia o serviço
Por que usar handlers?
- Eficiência: O serviço só reinicia se a configuração realmente mudou
- Ordem: Todas as tarefas são executadas primeiro, depois todos os handlers são executados no final
- Idempotência: Várias tarefas podem notificar o mesmo handler, mas ele só é executado uma vez
Salve e saia.
Finalmente, precisamos dizer ao Ansible que nossa role personalizada depende da role infra.apache que instalamos anteriormente.
nano roles/apache.developer_configs/meta/main.yml
Substitua o conteúdo do arquivo por:
---
dependencies:
- role: infra.apache ## Esta role deve ser executada antes da nossa role personalizada
O que isso faz:
- Quando o Ansible executar
apache.developer_configs, ele executará automaticamente infra.apache primeiro
- Isso garante que o Apache esteja instalado e configurado antes de adicionarmos nossas configurações personalizadas
- As dependências são executadas na ordem em que são listadas
Salve e saia.
4. Montar e Executar o Playbook Principal
Um playbook é como uma receita que diz ao Ansible o que fazer e em que ordem. Nosso playbook fará o seguinte:
- Configurar as configurações do SELinux (pre_tasks)
- Executar nossas roles (que inclui a cadeia de dependências)
Crie o arquivo do playbook principal:
nano web_dev_server.yml
Adicione o seguinte conteúdo com explicações detalhadas:
---
- name: Configure Dev Web Server ## Nome do Playbook
hosts: localhost ## Executa no localhost
pre_tasks: ## Tarefas que executam antes das roles
## Tarefa 1: Configurar o modo SELinux
- name: Set SELinux to enforcing mode
ansible.posix.selinux: ## Módulo da coleção ansible.posix
policy: targeted ## Usa a política SELinux 'targeted'
state: "{{ selinux_state }}" ## Usa a variável que definimos
when: selinux_state is defined ## Executa apenas se a variável existir
## Tarefa 2: Configurar portas SELinux
- name: Configure SELinux ports for Apache
community.general.seport: ## Módulo da coleção community.general
ports: "{{ item.ports }}" ## Número da porta
proto: "{{ item.proto }}" ## Protocolo (tcp)
setype: "{{ item.setype }}" ## Tipo SELinux (http_port_t)
state: "{{ item.state }}" ## present ou absent
loop: "{{ selinux_ports }}" ## Percorre nossa lista de portas
when: selinux_ports is defined ## Executa apenas se a variável existir
roles: ## Roles a serem executadas
- apache.developer_configs ## Nossa role personalizada (que acionará infra.apache)
Entendendo a ordem de execução:
pre_tasks: A configuração do SELinux é executada primeiro
roles: As dependências de roles são executadas (infra.apache), depois nossa role personalizada
handlers: Quaisquer handlers notificados são executados por último
Por que essa ordem é importante:
- O SELinux deve ser configurado antes que o Apache tente vincular-se a portas personalizadas
- O Apache deve ser instalado antes que possamos configurar virtual hosts
- Reinícios de serviço ocorrem após a conclusão de toda a configuração
Salve e saia.
Agora você está pronto para executar sua automação completa:
ansible-playbook web_dev_server.yml
O playbook será executado e você verá uma saída detalhada. Veja o que esperar (por exemplo):
PLAY [Configure Dev Web Server] *************************************************
TASK [Gathering Facts] **********************************************************
ok: [localhost] ## O Ansible coleta informações do sistema
TASK [Set SELinux to enforcing mode] *******************************************
changed: [localhost] ## O modo SELinux foi alterado
TASK [Configure SELinux ports for Apache] **************************************
changed: [localhost] => (item={'ports': '9081', 'proto': 'tcp', 'setype': 'http_port_t', 'state': 'present'})
changed: [localhost] => (item={'ports': '9082', 'proto': 'tcp', 'setype': 'http_port_t', 'state': 'present'})
TASK [infra.apache : Ensure Apache is installed.] *******************************
changed: [localhost] ## O pacote Apache foi instalado
TASK [apache.developer_configs : Create developer user accounts] ****************
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})
TASK [apache.developer_configs : Create developer web root directories] *********
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})
TASK [apache.developer_configs : Create a sample index.html for each developer] *
changed: [localhost] => (item={'username': 'jdoe', 'port': 9081})
changed: [localhost] => (item={'username': 'jdoe2', 'port': 9082})
TASK [apache.developer_configs : Deploy developer apache configs] ***************
changed: [localhost] ## O arquivo de configuração foi criado
RUNNING HANDLER [apache.developer_configs : restart apache] *********************
changed: [localhost] ## O Apache foi reiniciado
PLAY RECAP **********************************************************************
localhost : ok=17 changed=12 unreachable=0 failed=0 skipped=3 rescued=0 ignored=0
Você montou e executou com sucesso um playbook complexo que combina várias roles de diferentes fontes para criar um ambiente completo de desenvolvimento web!