Introdução
Idempotência significa que um playbook pode ser executado repetidamente e só altera o sistema quando o estado desejado está ausente ou diferente.
Neste laboratório, você usará módulos comuns do Ansible para criar diretórios e arquivos de configuração para aliases de hosts e, em seguida, executará o playbook duas vezes para provar que a segunda execução é estável.
Criar um Projeto de Prática de Idempotência
Nesta etapa, você criará um pequeno projeto Ansible com dois aliases de hosts gerenciados locais. Cada alias grava em seu próprio diretório para que você possa ver os resultados específicos do host enquanto permanece dentro de uma única VM RHEL 10.
Comece a partir do espaço de trabalho padrão do LabEx.
cd /home/labex/project
A opção -p instrui o mkdir a criar diretórios pai quando necessário e a concluir com sucesso caso o diretório já exista.
mkdir -p rhce-ansible/{inventory/group_vars,playbooks,managed,reports}
cd rhce-ansible
Crie os padrões do projeto que apontam o Ansible para o seu inventário e mantenha os arquivos de retry desativados.
cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
EOF
O diretório managed conterá os arquivos produzidos pelo playbook, enquanto o reports armazenará a saída salva do playbook. Manter esses diretórios separados facilita a comparação do conteúdo desejado com as evidências de execução do Ansible.
Definir Hosts Gerenciados Locais e Variáveis
Nesta etapa, você criará um inventário e variáveis de grupo. Os aliases usam ansible_connection=local, o que significa que o Ansible tem como alvo os hosts nomeados enquanto executa com segurança nesta VM.
Antes de executar os comandos nesta etapa, retorne ao diretório do projeto Ansible. Isso mantém os comandos estáveis, mesmo quando o LabEx executa cada etapa separadamente.
cd /home/labex/project/rhce-ansible
Crie dois aliases de host de aplicação em um grupo.
cat > inventory/hosts <<'EOF'
[app]
app1 ansible_connection=local
app2 ansible_connection=local
EOF
As variáveis de grupo descrevem o estado desejado compartilhado por todos os hosts do grupo.
cat > inventory/group_vars/app.yml <<'EOF'
app_owner: labex
app_environment: training
app_message: Managed by Ansible common modules
EOF
Confirme se o Ansible consegue visualizar os dois hosts.
ansible app --list-hosts
A saída deve listar app1 e app2. Esta verificação é útil antes de escrever um playbook, pois um play direcionado ao grupo app só pode afetar os hosts que o inventário resolve dentro desse grupo.
Escrever um Playbook de Estado Desejado
Nesta etapa, você escreverá um playbook que utiliza file, copy e lineinfile. Esses módulos descrevem o estado final em vez de executar comandos shell manualmente.
Antes de executar os comandos nesta etapa, retorne ao diretório do projeto Ansible. Isso mantém os comandos estáveis, mesmo quando o LabEx executa cada etapa separadamente.
cd /home/labex/project/rhce-ansible
Crie o playbook. Os caminhos incluem {{ inventory_hostname }} para que cada alias obtenha seu próprio diretório de saída.
cat > playbooks/common-modules.yml <<'EOF'
---
- name: Configure app host directories with common modules
hosts: app
gather_facts: false
tasks:
- name: Ensure host directory exists
ansible.builtin.file:
path: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}"
state: directory
mode: '0755'
- name: Install base application configuration
ansible.builtin.copy:
dest: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}/app.conf"
content: |
owner={{ app_owner }}
environment={{ app_environment }}
message={{ app_message }}
mode: '0644'
- name: Ensure managed message is present
ansible.builtin.lineinfile:
path: "/home/labex/project/rhce-ansible/managed/{{ inventory_hostname }}/app.conf"
line: "message={{ app_message }}"
create: true
mode: '0644'
EOF
A tarefa file cria o diretório, a tarefa copy grava a configuração completa e a tarefa lineinfile demonstra como aplicar uma única linha. Esses módulos comparam o estado atual com o estado desejado, razão pela qual podem ser idempotentes.
Use a verificação de sintaxe antes de executar um novo playbook.
ansible-playbook playbooks/common-modules.yml --syntax-check
Executar o Playbook e Inspecionar os Arquivos
Nesta etapa, você executará o playbook de estado desejado pela primeira vez. A primeira execução deve relatar alterações, pois os arquivos de destino ainda não existem. Antes de executar os comandos nesta etapa, retorne ao diretório do projeto Ansible. Isso mantém os comandos estáveis, mesmo quando o LabEx executa cada etapa separadamente.
cd /home/labex/project/rhce-ansible
Execute o playbook e salve a saída para comparação posterior.
ansible-playbook playbooks/common-modules.yml | tee reports/first-run.txt
A primeira execução deve relatar alterações porque os diretórios dos hosts e os arquivos app.conf são novos. O tee permite que você acompanhe a execução enquanto salva a mesma saída para a verificação de idempotência.
Inspecione os arquivos específicos do host que o Ansible criou.
cat managed/app1/app.conf managed/app2/app.conf
Ambos os arquivos devem conter os mesmos valores de proprietário, ambiente e mensagem, mas residem em diretórios de alias de host diferentes. Isso mostra que o playbook aplicou o mesmo estado desejado a cada host do inventário.
Executar o Playbook Novamente para Comprovar a Idempotência
Nesta etapa, você executará o mesmo playbook novamente. Como os arquivos já correspondem ao estado desejado, o Ansible deve relatar zero alterações para ambos os hosts. Antes de executar os comandos nesta etapa, retorne ao diretório do projeto Ansible. Isso mantém os comandos estáveis, mesmo quando o LabEx executa cada etapa separadamente.
cd /home/labex/project/rhce-ansible
Execute o playbook uma segunda vez e salve a saída.
ansible-playbook playbooks/common-modules.yml | tee reports/second-run.txt
Procure por changed=0 nas linhas de resumo (recap).
grep -E 'app[12].*changed=0' reports/second-run.txt
changed=0 na segunda execução é o principal sinal de idempotência. Isso significa que os módulos inspecionaram os arquivos existentes e constataram que nenhum reparo era necessário.
Resumo
Você construiu um projeto Ansible, usou módulos comuns para descrever o estado desejado, executou o playbook e comprovou a idempotência com uma segunda execução que não relatou alterações.


