Introduction
Un seul playbook peut sélectionner des travaux différents pour chaque hôte sans dupliquer toute la liste de tâches. Vous combinerez des entrées de politique booléennes avec les faits du système d'exploitation, traiterez chaque élément d'une liste structurée et utiliserez des résultats d'inspection réellement enregistrés pour une décision d'approbation indépendante. Des fichiers réels et un nettoyage explicite rendront observables les comportements sélectionnés et ignorés.
Sélectionner des tâches avec des entrées booléennes et des faits
Dans cette étape, vous ferez agir un playbook réutilisable différemment sur les deux hôtes et supprimerez explicitement les sorties lorsque la politique devient désactivée.
L'environnement préparé possède une entrée d'approbation séparée dans /home/automation/maintenance-approved uniquement sur web1. Laissez cette entrée inchangée pour le moment ; la première décision de politique utilise plutôt une variable booléenne et les faits découverts du système d'exploitation.
Entrez dans le projet du contrôleur :
cd /home/labex/project
Les fichiers de variables d'hôte associent des données à chaque nom d'inventaire. Écrivez les valeurs booléennes YAML sans guillemets afin qu'elles restent des valeurs true/false plutôt que des chaînes :
cat > host_vars/web1.yml <<'YAML'
maintenance_enabled: true
YAML
cat > host_vars/web2.yml <<'YAML'
maintenance_enabled: false
YAML
Le mot-clé when évalue une expression booléenne pour l'hôte actuel. N'entourez pas l'expression d'accolades Jinja. Ici, and exige à la fois une politique activée et des faits de famille Debian. not inverse un booléen et or permet à l'une ou l'autre raison de sélectionner la branche de nettoyage.
cat > maintenance.yml <<'YAML'
- name: Apply a host-specific maintenance policy
hosts: all
gather_facts: true
tasks:
- name: Prepare the common policy directory
ansible.builtin.file:
path: /home/automation/maintenance-policy
state: directory
mode: "0750"
- name: Record enabled Debian maintenance
ansible.builtin.copy:
dest: /home/automation/maintenance-policy/enabled.txt
content: "Enabled maintenance\n"
mode: "0640"
when: maintenance_enabled and ansible_facts.os_family == "Debian"
- name: Remove the marker when the policy is disabled
ansible.builtin.file:
path: /home/automation/maintenance-policy/enabled.txt
state: absent
when: not maintenance_enabled or ansible_facts.os_family != "Debian"
YAML
Le répertoire commun existe sur les deux hôtes. Seuls les hôtes Debian activés reçoivent le fichier témoin ; la tâche absent complémentaire le supprime lorsque la politique est désactivée. Une tâche de création simplement ignorée laisserait un ancien fichier témoin : le nettoyage est donc une tâche distincte d'état souhaité.
Validez et appliquez la politique :
ansible-playbook maintenance.yml --syntax-check
ansible-playbook maintenance.yml
La sortie doit montrer des décisions changed/ok/skipped différentes pour web1 et web2. Examinez les métadonnées du véritable fichier témoin sur les deux hôtes :
ansible all -m ansible.builtin.stat -a 'path=/home/automation/maintenance-policy/enabled.txt'
Stat doit indiquer exists true sur web1 et false sur web2. Pour exercer le nettoyage, remplacez le booléen pour les deux hôtes. Les variables supplémentaires JSON préservent le type booléen false ; les guillemets simples englobants protègent le JSON de l'interprétation du shell :
ansible-playbook maintenance.yml -e '{"maintenance_enabled":false}'
ansible all -m ansible.builtin.stat -a 'path=/home/automation/maintenance-policy/enabled.txt'
Les deux fichiers témoins doivent maintenant être absents. Rétablissez la politique enregistrée par hôte en exécutant sans le remplacement temporaire :
ansible-playbook maintenance.yml
Web1 doit retrouver le fichier témoin tandis que web2 reste désactivé. Le remplacement n'a pas modifié les fichiers de variables d'hôte enregistrés.
Appliquer chaque élément d'une boucle structurée
Dans cette étape, vous produirez un véritable enregistrement de vérification de maintenance pour chaque élément déclaré sur l'hôte activé.
Une liste YAML contient plusieurs entrées introduites par un tiret. Chaque entrée ci-dessous est une correspondance avec les champs name et purpose. Les variables de groupe pour all rendent cette liste disponible aux deux hôtes, tandis que la condition booléenne existante décide toujours quel hôte reçoit les sorties.
cat > group_vars/all.yml <<'YAML'
maintenance_checks:
- name: disk
purpose: Inspect disk space
- name: logs
purpose: Inspect application logs
- name: packages
purpose: Inspect package state
YAML
loop répète une tâche pour chaque entrée de liste. Dans une itération, item.name et item.purpose lisent les champs de cette entrée. La condition when est évaluée pour chaque hôte et élément. Ajoutez ces tâches au playbook existant en alignant l'indentation avec les tâches précédentes :
cat >> maintenance.yml <<'YAML'
- name: Prepare checks only for enabled Debian hosts
ansible.builtin.file:
path: /home/automation/maintenance-policy/checks
state: directory
mode: "0750"
when: maintenance_enabled and ansible_facts.os_family == "Debian"
- name: Write every declared maintenance check
ansible.builtin.copy:
dest: "/home/automation/maintenance-policy/checks/{{ item.name }}.txt"
content: |
host={{ inventory_hostname }}
check={{ item.name }}
purpose={{ item.purpose }}
mode: "0640"
loop: "{{ maintenance_checks }}"
when: maintenance_enabled and ansible_facts.os_family == "Debian"
- name: Remove check outputs when the policy is disabled
ansible.builtin.file:
path: /home/automation/maintenance-policy/checks
state: absent
when: not maintenance_enabled or ansible_facts.os_family != "Debian"
YAML
La tâche de nettoyage supprime tout le répertoire de vérifications sur les hôtes désactivés, y compris les anciennes sorties d'une politique précédemment activée. La boucle écrit un contenu stable et des permissions explicites sur les hôtes activés.
Appliquez le playbook étendu :
ansible-playbook maintenance.yml
Web1 doit avoir trois résultats de boucle, un par vérification. Web2 doit ignorer ces écritures et ne conserver aucun répertoire checks. Lisez les trois artefacts réels de web1 au lieu de considérer un seul élément réussi comme preuve pour toute la liste :
ansible web1 -m ansible.builtin.command -a 'cat /home/automation/maintenance-policy/checks/disk.txt /home/automation/maintenance-policy/checks/logs.txt /home/automation/maintenance-policy/checks/packages.txt'
La sortie doit identifier host=web1 pour chaque enregistrement et montrer le nom et le but de la vérification correspondante. Examinez l'hôte désactivé indépendamment :
ansible web2 -m ansible.builtin.stat -a 'path=/home/automation/maintenance-policy/checks'
Son résultat stat doit indiquer exists false. Ces enregistrements déclarent des instructions de vérification de maintenance ; ils ne prétendent pas exécuter eux-mêmes les inspections du disque, des journaux ou des paquets.
Choisir une branche selon un résultat d'inspection enregistré
Dans cette étape, vous utiliserez un véritable résultat stat comme entrée de décision indépendante et confirmerez que la politique complète est stable lors d'une répétition.
L'entrée d'approbation est distincte de maintenance_enabled. Une tâche stat examine toujours chaque hôte, puis register stocke son résultat. Son booléen stat.exists distingue de manière sûre une entrée existante d'un chemin absent. Ajoutez l'inspection et les tâches de sortie complémentaires :
cat >> maintenance.yml <<'YAML'
- name: Inspect the independent approval input
ansible.builtin.stat:
path: /home/automation/maintenance-approved
register: approval_info
- name: Record an existing approval input
ansible.builtin.copy:
dest: /home/automation/maintenance-policy/approved.txt
content: "Approval input exists\n"
mode: "0640"
when: approval_info.stat.exists
- name: Remove the output when approval input is absent
ansible.builtin.file:
path: /home/automation/maintenance-policy/approved.txt
state: absent
when: not approval_info.stat.exists
YAML
La tâche copy consomme la valeur exists enregistrée. La tâche absent couvre son opposé afin que la suppression d'une entrée d'approbation supprime aussi la sortie d'approbation périmée. Cette branche repose sur l'état inspecté plutôt que sur un message debug fixe.
Exécutez la politique complète :
ansible-playbook maintenance.yml
L'entrée d'approbation préparée n'existe que sur web1 ; seul web1 doit donc avoir approved.txt. Examinez les deux chemins de sortie réels :
ansible all -m ansible.builtin.stat -a 'path=/home/automation/maintenance-policy/approved.txt'
Web1 doit indiquer exists true et web2 false. Répétez le playbook :
ansible-playbook maintenance.yml
Les deux lignes du récapitulatif doivent indiquer changed=0, failed=0 et unreachable=0. Des tâches ignorées sont attendues lorsque leur condition est fausse ; chaque élément de boucle requis et chaque sortie sélectionnée doivent toutefois exister avec le bon contenu.
Résumé
Vous avez utilisé des données booléennes par hôte et des faits découverts pour sélectionner les tâches, traité chaque correspondance dans une boucle et choisi des branches selon des métadonnées stat enregistrées. Des tâches absent complémentaires ont supprimé les sorties périmées au lieu de supposer qu'une création ignorée annule l'ancien état. Les deux hôtes ont convergé vers leurs résultats de politique distincts sans changements répétés inutiles.


