Skip to content

Compte rendu de TP : Variables enregistrées et exécution de commandes (Atelier 15)

Objectif

Apprendre à exécuter des commandes système classiques à l'intérieur d'un playbook, capturer leur résultat avec la directive register, et l'afficher. Forcer l'idempotence de ces commandes de lecture seules avec changed_when: false.

Durée

~25 minutes

Objectif du TP

L'objectif de cet atelier est d'apprendre à exécuter des commandes système classiques (qui ne disposent pas de modules ansible dédiés) à l'intérieur d'un playbook, de capturer leur résultat grâce à la directive register, et de l'afficher. Nous apprenons également à forcer l'idempotence de ces commandes de lecture seules avec la directive changed_when: false.


1. Préparation de l'environnement

Après avoir démarré les machines de l'atelier (vagrant up) et nous être connectés au nœud de contrôle (vagrant ssh ansible), nous chargeons l'environnement du projet via direnv :

cd ~/ansible/projets/ema/

Nous nous plaçons ensuite dans le répertoire dédié à la création de nos playbooks :

cd playbooks


2. Affichage des informations du noyau (kernel.yml)

Notre premier objectif est d'exécuter la commande uname -a sur l'ensemble de notre parc, de stocker le résultat, puis de l'afficher de deux manières différentes.

Variante 1 : Affichage avec le paramètre msg

Nous créons un premier fichier kernel.yml en utilisant le module command et en formatant l'affichage avec le paramètre msg du module debug :

---
# kernel.yml
- hosts: all
  gather_facts: false
  tasks:
    - name: Get kernel information
      command: uname -a
      register: kernel_info
      changed_when: false

    - name: Display kernel info (using msg)
      debug:
        msg: "Informations du noyau : {{ kernel_info.stdout }}"
...

Note : La directive changed_when: false est cruciale ici. Elle indique à ansible que la commande uname -a ne fait que lire des informations sans altérer le système, ce qui évite de fausser les statistiques de modification (le statut restera sur ok au lieu de changed).

Exécution du playbook :

Exécution de kernel.yml avec le paramètre msg

Comme l'illustre la capture ci-dessus (img01.png), la commande renvoie les informations spécifiques au noyau de chaque distribution (Rocky, Debian, SUSE) de manière formatée. Le récapitulatif (PLAY RECAP) confirme que changed=0, validant notre directive d'idempotence.

Variante 2 : Affichage avec le paramètre var

Le module debug propose une syntaxe alternative plus directe avec le paramètre var, qui n'utilise pas les doubles accolades {{ }}. Nous adaptons la tâche d'affichage de notre playbook :

    - name: Display kernel info (using var)
      debug:
        var: kernel_info.stdout

Exécution de cette seconde variante :

Exécution de kernel.yml avec le paramètre var

L'image ci-dessus (img02.png) montre que cette approche retourne un format de type clé/valeur ("kernel_info.stdout": "Linux..."), ce qui est particulièrement utile et lisible pour le débogage de structures complexes lors du développement de playbooks.


3. Comptage des paquets RPM (packages.yml)

Le deuxième exercice consiste à compter le nombre de paquets RPM installés sur nos machines compatibles (Rocky Linux et SUSE Linux).

Détail technique : La commande demandée (rpm -qa | wc -l) utilise un tube (pipe |). Le module ansible command ne gérant pas les opérateurs shell (comme |, >, <), il est obligatoire d'utiliser le module shell pour cette tâche.

Nous créons le fichier packages.yml en ciblant spécifiquement les hôtes rocky et suse :

---
# packages.yml
- hosts: rocky, suse
  gather_facts: false
  tasks:
    - name: Count installed RPM packages
      shell: rpm -qa | wc -l
      register: rpm_count
      changed_when: false

    - name: Display package count
      debug:
        msg: "Nombre total de paquets RPM installés : {{ rpm_count.stdout }}"
...

Exécution du playbook :

Comptage des paquets RPM sur Rocky et SUSE

Le résultat (img03.png) affiche l'exécution ciblée sur les nœuds Rocky et SUSE. La commande remonte avec succès la valeur numérique exacte calculée sur chaque système : 642 paquets pour Rocky Linux, et 504 paquets pour SUSE Linux. Encore une fois, la tâche est marquée en ok sans altérer le système (changed=0).


4. Nettoyage de l'environnement

L'atelier étant terminé et le comportement des variables enregistrées parfaitement assimilé, nous quittons le Control Host et procédons à la suppression des machines virtuelles :

exit
vagrant destroy -f

Je retiens

  • register capture le résultat d'une tâche dans une variable réutilisable (.stdout, .stderr, .rc...).
  • changed_when: false force le statut ok pour les commandes en lecture seule (pas de modification système).
  • debug avec msg formate l'affichage librement ; debug avec var donne un format clé/valeur brut (utile pour le debug).
  • Le module shell est nécessaire dès qu'un pipe (|) ou une redirection est utilisée, contrairement à command (cf. Workshop 05).

Cheatsheet

Symptôme Cause probable Correction
kernel_info.stdoutundefined variable register: oublié sur la tâche qui produit la sortie Ajouter register: kernel_info sur la tâche command:
Sortie sur plusieurs lignes concaténée dans .stdout .stdout est une chaîne unique Utiliser .stdout_lines qui renvoie une liste, plus pratique avec debug: var=...
rpm -qa \| wc -l → échec avec le module command command n'interprète pas le pipe Passer au module shell (cf. Workshop 05)
La tâche reste marquée changed alors qu'elle ne modifie rien command / shell sont changed par défaut Ajouter changed_when: false (ou une condition basée sur .rc / .stdout)
failed: task ... sans message clair Le code retour n'est pas 0 et failed_when n'est pas défini Utiliser ignore_errors: true pour déboguer, puis affiner avec failed_when: kernel_info.rc != 0
La variable register n'est pas accessible dans une autre play Les register ont une portée par hôte et par play ; elles ne sont pas partagées entre plays Utiliser set_fact pour promouvoir la valeur si besoin d'une persistance inter-play

Sources (principales)


Précédent : Variables Suite : Facts + Implicit Vars