Três decisões diferentes
Uma configuração pode ter sintaxe válida e ainda assim falhar a necessidade do negócio. Separa a validação do ficheiro candidato, a instalação dos bytes e a aceitação do serviço. Neste exercício, o candidato tem exatamente worker e port; o worker deve pertencer ao conjunto esperado e a porta deve estar entre 1024 e 65535. Estas regras pertencem ao cenário fictício. Não são uma configuração universal de aplicações bancárias. O validador Python lê o caminho temporário recebido por validate. Se rejeitar a porta 70000, o template não deve substituir o worker.conf anterior.
Observar a primeira execução e a repetição
Executa converge.yml com service_port=8443. O template instala o ficheiro com modo 0600 e notifica o handler que acrescenta uma linha ao log de ativação. O flush_handlers coloca esse efeito antes da inspeção final. No laboratório, uma linha equivale apenas à execução do handler; não há processo de aplicação a reiniciar. Repete o mesmo comando e compara conteúdo, modo e número de linhas. O recap deve indicar zero alterações e o log deve continuar com uma linha por worker. Se o template incluísse um timestamp variável, a repetição deixaria de representar a mesma entrada, mesmo que a intenção funcional não tivesse mudado.
Injetar uma proposta inválida
O runner guarda os bytes aprovados antes de tentar a porta 70000. A execução deve falhar e os bytes devem permanecer iguais nos dois destinos. Também confirma que o log de ativação não cresceu. Esta combinação é mais útil que procurar a palavra failed isoladamente: comprova rejeição do candidato e conservação do estado observado. Um validador que examina sempre o ficheiro já instalado, ignorando %s, poderia aprovar um candidato mau porque leu a versão antiga. Testa deliberadamente esse caso ao rever um validador da tua equipa.
Interpretar check mode
O ensaio seguinte propõe 9443 com --check. O ficheiro real permanece em 8443. Uma previsão de changed não significa que o serviço foi alterado; o handler command também não constitui prova de ativação neste modo. Examina tarefas com check_mode: false antes de tratar um ensaio como não mutável. Em produção, junta uma sonda funcional após a ativação e define o que fazer se a sintaxe passa mas a reconciliação falha. Regista separadamente candidato válido, configuração instalada, processo saudável e resultado de negócio aceite.
# File: converge.yml
- name: Validate and converge synthetic worker configuration
hosts: workers
gather_facts: false
vars:
node_dir: "{{ lab_root }}/{{ inventory_hostname }}"
tasks:
- name: Create isolated worker directory
ansible.builtin.file:
path: "{{ node_dir }}"
state: directory
mode: '0700'
- name: Validate before replacing the destination
ansible.builtin.template:
src: config.j2
dest: "{{ node_dir }}/worker.conf"
mode: '0600'
validate: "{{ ansible_playbook_python }} {{ playbook_dir }}/validate.py %s"
notify: Record activation
- name: Finish activation before acceptance
ansible.builtin.meta: flush_handlers
- name: Inspect persisted file content
ansible.builtin.stat:
path: "{{ node_dir }}/worker.conf"
checksum_algorithm: sha256
register: observed
- name: Require a private regular file after normal execution
ansible.builtin.assert:
that:
- observed.stat.isreg
- observed.stat.mode == '0600'
when: not ansible_check_mode
handlers:
- name: Record activation
ansible.builtin.command:
argv:
- "{{ ansible_playbook_python }}"
- -c
- "import pathlib,sys; p=pathlib.Path(sys.argv[1]); p.open('a').write('activated' + chr(10))"
- "{{ node_dir }}/activation.log"
# File: config.j2
worker={{ inventory_hostname }}
port={{ service_port }}
# File: validate.py
import pathlib,sys
lines=pathlib.Path(sys.argv[1]).read_text().splitlines()
values=dict(line.split('=',1) for line in lines)
assert set(values)=={'worker','port'}
assert values['worker'] in {'worker_a','worker_b'}
assert 1024<=int(values['port'])<=65535
A porta 70000 falha antes da substituição; os hashes e o log anterior mantêm-se.
Armadilhas comuns
Validar o destino antigo; ativar antes da validação; contar previsão como alteração aplicada.
Tópicos relacionados: Ensaio executável: âmbito, estado e limites · Arquivos, ficheiros residuais e marcadores · Recuperação e resultado da mudança
Valida o candidato e observa instalação, ativação e aceitação com critérios próprios.
Referência: Template module · EX294 current objectives inspected 2026-09-30; RHCE in Ansible framework effective 2026-05-11; booking product version not publicly pinned