Organizar automação reutilizável em uma role

AnsibleBeginner
Pratique Agora

Introdução

Roles organizam uma unidade funcional de automação para que os consumidores possam fornecer dados sem duplicar a implementação. Você criará uma role com valores padrão públicos, renderizará páginas específicas por host, manterá a validação da configuração e o comportamento de recarga dentro da role e a reutilizará em dois grupos do inventário. Arquivos gerenciados reais e respostas HTTP verificarão que a role é realmente invocada.

Criar e invocar uma role com valores padrão

Nesta etapa, você moverá a automação do site para uma role e a invocará por um playbook curto usando entradas padrão reutilizáveis.

Uma role agrupa tarefas relacionadas, variáveis padrão, modelos e handlers em um diretório padrão. Seu tasks/main.yml é o ponto de entrada das tarefas; defaults/main.yml fornece valores de baixa precedência que os consumidores podem substituir. As origens dos modelos ficam em templates, e handlers/main.yml conterá posteriormente ações de serviço acionadas por alterações.

O inventário preparado já coloca web1 em canary e web2 em stable, sob o grupo pai sites. O nginx está instalado como pré-requisito. Inspecione os grupos:

cd /home/labex/project
ansible-inventory --graph

Crie os diretórios da role com mkdir -p. Vários argumentos de caminho criam cada diretório nomeado:

mkdir -p roles/managed_site/tasks roles/managed_site/defaults roles/managed_site/templates roles/managed_site/handlers

Use o prefixo site_ nas variáveis públicas da role para deixar clara sua finalidade. Comece com padrões compartilhados que qualquer consumidor possa usar:

cat > roles/managed_site/defaults/main.yml <<'YAML'
site_environment: training
site_port: 8080
site_maintenance: false
YAML

O modelo da página usa a entrada da role junto ao nome de cada destino e à distribuição coletada:

cat > roles/managed_site/templates/page.txt.j2 <<'JINJA'
host={{ inventory_hostname }}
environment={{ site_environment }}
distribution={{ ansible_facts.distribution }}
JINJA

Crie o ponto de entrada das tarefas da role. Dentro de uma role, src: page.txt.j2 é resolvido no diretório templates dessa role; o destino continua sendo um caminho gerenciado absoluto:

cat > roles/managed_site/tasks/main.yml <<'YAML'
- name: Prepare the role-managed website directory
  ansible.builtin.file:
    path: /var/www/role-site
    state: directory
    owner: root
    group: root
    mode: "0755"

- name: Render the role-managed page
  ansible.builtin.template:
    src: page.txt.j2
    dest: /var/www/role-site/index.html
    owner: root
    group: root
    mode: "0644"
YAML

Invoque a role com a palavra-chave roles. O play que a envolve seleciona os destinos, coleta fatos e solicita become; a role fornece as tarefas reutilizáveis:

cat > site.yml <<'YAML'
- name: Apply the managed site role with defaults
  hosts: sites
  gather_facts: true
  become: true
  roles:
    - managed_site
YAML

Valide e execute a role por seu playbook consumidor:

ansible-playbook site.yml --syntax-check
ansible-playbook site.yml

Inspecione as páginas reais criadas pela role:

ansible sites -m ansible.builtin.command -a 'cat /var/www/role-site/index.html'

Ambas devem mostrar environment=training a partir do padrão, com seus próprios nomes de host e distribution=Ubuntu. Apenas criar os diretórios da role não a executaria nem criaria esses arquivos gerenciados.

Manter modelos e handlers dentro da role reutilizável

Nesta etapa, você fará a role configurar e executar o site, incluindo a validação do candidato e seu próprio handler de recarga.

Coloque o modelo nginx completo junto à origem da página. Ele usa as entradas site_ da role, o filtro upper já praticado e um ramo booleano:

cat > roles/managed_site/templates/nginx.conf.j2 <<'JINJA'
events {}
http {
    server_tokens off;
    server {
        listen {{ site_port }};
        root /var/www/role-site;
        index index.html;
        add_header X-Environment "{{ site_environment | upper }}" always;
{% if site_maintenance %}
        add_header X-Maintenance "enabled" always;
{% else %}
        add_header X-Maintenance "disabled" always;
{% endif %}
    }
}
JINJA

Acrescente tarefas da role que validem a configuração renderizada antes da substituição e mantenham explicitamente o nginx iniciado. A configuração alterada notifica o handler nomeado da role:

cat >> roles/managed_site/tasks/main.yml <<'YAML'

- name: Render and validate the role-managed nginx configuration
  ansible.builtin.template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
    owner: root
    group: root
    mode: "0644"
    validate: /usr/sbin/nginx -t -c %s
  notify: Reload managed site

- name: Keep the role-managed service running
  ansible.builtin.service:
    name: nginx
    state: started
YAML

Escreva o handler no ponto de entrada de handlers da role, em vez de duplicá-lo em cada playbook consumidor:

cat > roles/managed_site/handlers/main.yml <<'YAML'
- name: Reload managed site
  ansible.builtin.service:
    name: nginx
    state: reloaded
YAML

Execute o playbook consumidor inalterado. A role agora fornece seu comportamento completo de implantação:

ansible-playbook site.yml

Os dois hosts devem iniciar seus próprios sites na porta padrão 8080. Inspecione cada destino por seu próprio endereço de loopback:

ansible sites -m ansible.builtin.command -a 'curl --fail --silent --show-error -i http://127.0.0.1:8080/'

Cada corpo deve identificar seu próprio host e environment=training. Os cabeçalhos devem incluir X-Environment: TRAINING e X-Maintenance: disabled. A saída vem de serviços em execução configurados pela role, em vez de uma demonstração apenas no controlador.

Reutilizar a mesma role com substituições por variáveis de grupo

Nesta etapa, você aplicará a mesma role a dois contextos de grupos sem editar seus padrões reutilizáveis nem seus arquivos de tarefas.

Os padrões da role têm baixa precedência deliberadamente. As variáveis de grupo do inventário podem substituir essas entradas públicas, mantendo a mesma implementação. Mantenha defaults/main.yml inalterado e crie os dados consumidores de cada grupo:

cat > group_vars/canary.yml <<'YAML'
site_environment: development
site_port: 8081
site_maintenance: true
YAML
cat > group_vars/stable.yml <<'YAML'
site_environment: production
site_port: 8082
site_maintenance: false
YAML

Substitua o playbook consumidor por dois plays que invocam a mesma role managed_site. Cada grupo recebe suas próprias entradas resolvidas. Não duplique o diretório da role para cada ambiente:

cat > site.yml <<'YAML'
- name: Apply the shared role to canary
  hosts: canary
  gather_facts: true
  become: true
  roles:
    - managed_site

- name: Apply the shared role to stable
  hosts: stable
  gather_facts: true
  become: true
  roles:
    - managed_site
YAML

Valide e aplique os dois contextos:

ansible-playbook site.yml --syntax-check
ansible-playbook site.yml

Os dois ambientes devem carregar suas configurações alteradas pelo handler local da role. Inspecione os destinos reais em suas novas portas configuradas:

ansible canary -m ansible.builtin.command -a 'curl --fail --silent --show-error -i http://127.0.0.1:8081/'
ansible stable -m ansible.builtin.command -a 'curl --fail --silent --show-error -i http://127.0.0.1:8082/'

Canary deve identificar web1 e development, com cabeçalhos DEVELOPMENT/enabled. Stable deve identificar web2 e production, com cabeçalhos PRODUCTION/disabled. Essas diferenças vêm das entradas de grupo, enquanto uma role compartilhada continua responsável pelos padrões, tarefas, modelos e handlers.

Repita o mesmo playbook consumidor:

ansible-playbook site.yml

As duas linhas do resumo devem informar changed=0, unreachable=0 e failed=0, sem handler agendado. Uma role reutilizável precisa ser invocada e produzir um estado gerenciado convergido correto; apenas uma estrutura de diretórios não é uma implantação.

Resumo

Você organizou padrões, tarefas, modelos e handlers em uma role invocada. Padrões de baixa precedência permitiram substituições por consumidores, e dois grupos do inventário reutilizaram a mesma implementação para produzir serviços reais distintos. A validação de candidatos, as recargas acionadas por alterações e a execução repetida sem alterações continuaram fazendo parte da unidade reutilizável.