Écrire des playbooks idempotents avec des modules courants

AnsibleBeginner
Pratiquer maintenant

Introduction

L'idempotence signifie qu'un playbook peut être exécuté de manière répétée sans modifier le système, à moins que l'état souhaité ne soit absent ou différent de l'état actuel.

Dans ce laboratoire, vous utiliserez des modules Ansible courants pour créer des répertoires et des fichiers de configuration pour des alias d'hôtes, puis vous exécuterez le playbook deux fois pour prouver que la seconde exécution est stable.

Créer un projet de pratique pour l'idempotence

Dans cette étape, vous allez créer un petit projet Ansible avec deux alias d'hôtes gérés localement. Chaque alias écrit dans son propre répertoire afin que vous puissiez observer les résultats spécifiques à chaque hôte tout en restant dans une seule machine virtuelle RHEL 10.

Commencez depuis l'espace de travail LabEx par défaut.

cd /home/labex/project

L'option -p indique à mkdir de créer les répertoires parents si nécessaire et de réussir l'opération si un répertoire existe déjà.

mkdir -p rhce-ansible/{inventory/group_vars,playbooks,managed,reports}
cd rhce-ansible

Créez les paramètres par défaut du projet qui pointent Ansible vers votre inventaire et désactivent les fichiers de réessai (retry files).

cat > ansible.cfg <<'EOF'
[defaults]
inventory = ./inventory/hosts
host_key_checking = False
retry_files_enabled = False
EOF

Le répertoire managed contiendra les fichiers produits par le playbook, tandis que reports conservera les sorties enregistrées du playbook. Garder ces éléments séparés facilite la comparaison entre le contenu souhaité et les preuves d'exécution d'Ansible.

Définir les hôtes gérés localement et les variables

Dans cette étape, vous allez créer un inventaire et des variables de groupe. Les alias utilisent ansible_connection=local, ce qui signifie qu'Ansible cible les hôtes nommés tout en s'exécutant en toute sécurité sur cette machine virtuelle. Avant d'exécuter les commandes de cette étape, retournez dans le répertoire du projet Ansible. Cela garantit la stabilité des commandes, même si LabEx exécute chaque étape séparément.

cd /home/labex/project/rhce-ansible

Créez deux alias d'hôtes d'application dans un groupe.

cat > inventory/hosts <<'EOF'
[app]
app1 ansible_connection=local
app2 ansible_connection=local
EOF

Les variables de groupe décrivent l'état souhaité partagé par chaque hôte du groupe.

cat > inventory/group_vars/app.yml <<'EOF'
app_owner: labex
app_environment: training
app_message: Managed by Ansible common modules
EOF

Confirmez qu'Ansible peut voir les deux hôtes.

ansible app --list-hosts

La sortie doit lister app1 et app2. Cette vérification est utile avant d'écrire un playbook, car un play ciblant app ne peut affecter que les hôtes que l'inventaire résout dans ce groupe.

Écrire un playbook d'état souhaité

Dans cette étape, vous allez écrire un playbook qui utilise file, copy et lineinfile. Ces modules décrivent l'état final au lieu d'exécuter manuellement des commandes shell. Avant d'exécuter les commandes de cette étape, retournez dans le répertoire du projet Ansible.

cd /home/labex/project/rhce-ansible

Créez le playbook. Les chemins incluent {{ inventory_hostname }} afin que chaque alias obtienne son propre répertoire de sortie.

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

La tâche file crée le répertoire, la tâche copy écrit la configuration complète, et la tâche lineinfile démontre comment appliquer une ligne spécifique. Ces modules comparent l'état actuel avec l'état souhaité, ce qui leur permet d'être idempotents.

Vérifiez la syntaxe avant d'exécuter un nouveau playbook.

ansible-playbook playbooks/common-modules.yml --syntax-check

Exécuter le playbook et inspecter les fichiers

Dans cette étape, vous allez exécuter le playbook d'état souhaité pour la première fois. La première exécution devrait signaler des changements car les fichiers cibles n'existent pas encore. Avant d'exécuter les commandes de cette étape, retournez dans le répertoire du projet Ansible.

cd /home/labex/project/rhce-ansible

Exécutez le playbook et enregistrez la sortie pour une comparaison ultérieure.

ansible-playbook playbooks/common-modules.yml | tee reports/first-run.txt

La première exécution doit signaler des changements car les répertoires d'hôtes et les fichiers app.conf sont nouveaux. tee vous permet de visualiser l'exécution tout en enregistrant la sortie pour la vérification de l'idempotence.

Inspectez les fichiers spécifiques aux hôtes créés par Ansible.

cat managed/app1/app.conf managed/app2/app.conf

Les deux fichiers doivent contenir les mêmes valeurs de propriétaire, d'environnement et de message, mais ils se trouvent dans des répertoires d'alias d'hôtes différents. Cela montre que le playbook a appliqué le même état souhaité à chaque hôte de l'inventaire.

Exécuter à nouveau le playbook pour prouver l'idempotence

Dans cette étape, vous allez exécuter le même playbook une seconde fois. Comme les fichiers correspondent déjà à l'état souhaité, Ansible devrait signaler zéro changement pour les deux hôtes. Avant d'exécuter les commandes de cette étape, retournez dans le répertoire du projet Ansible.

cd /home/labex/project/rhce-ansible

Exécutez le playbook une seconde fois et enregistrez la sortie.

ansible-playbook playbooks/common-modules.yml | tee reports/second-run.txt

Recherchez changed=0 dans les lignes de récapitulatif.

grep -E 'app[12].*changed=0' reports/second-run.txt

changed=0 lors de la seconde exécution est le signal clé de l'idempotence. Cela signifie que les modules ont inspecté les fichiers existants et ont constaté qu'aucune réparation n'était nécessaire.

Résumé

Vous avez construit un projet Ansible, utilisé des modules courants pour décrire l'état souhaité, exécuté le playbook et prouvé l'idempotence avec une seconde exécution qui n'a signalé aucun changement.