
Pendant l'exécution d'un playbook, vous avez souvent besoin de capturer une sortie de module et de la réutiliser plus loin. C'est le rôle de register: (capture la sortie d'une tâche) et set_fact: (crée une variable au runtime). Cette page explique la différence, les champs disponibles dans un register: (stdout, rc, delta...), la durée de vie des variables, et l'option cacheable: true qui rend un fact persistant entre runs via le fact caching.
C'est l'outil de prédilection pour chaîner des tâches : récupérer un version, calculer un identifiant, conditionner une suite d'actions sur le résultat d'une commande.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »register: varcapture la sortie complète d'un module (rc, stdout, stderr, delta...)- Accéder aux champs :
var.stdout,var.rc,var.changed,var.failed set_fact:crée une variable de runtime, scope du play entiercacheable: truerend le fact persistant via fact_caching (jsonfile/redis/memcached)- La différence entre
register(lié à la tâche),set_fact(manuel) et les facts (gather)
Prérequis
Section intitulée « Prérequis »- Avoir lu les pages précédentes de la sous-section Variables et facts.
register:, capturer la sortie d'un module
Section intitulée « register:, capturer la sortie d'un module »- name: Récupérer le hostname ansible.builtin.command: hostname -s register: hostname_result changed_when: false
- name: Afficher ansible.builtin.debug: msg: "stdout={{ hostname_result.stdout }} rc={{ hostname_result.rc }}"hostname_result contient tout ce que le module a retourné. Pour le module command :
| Champ | Contenu |
|---|---|
stdout | Sortie standard (string) |
stdout_lines | Sortie standard (liste de lignes) |
stderr | Sortie d'erreur |
stderr_lines | Idem en liste |
rc | Exit code (0 = succès) |
cmd | La commande exécutée |
start, end, delta | Timestamps |
changed, failed, skipped | Status booléens |
Pour les autres modules, les champs varient. Exemple avec uri :
- name: Appeler une API ansible.builtin.uri: url: http://localhost return_content: true register: api_responseapi_response contient :
status: code HTTP retournécontent: corps de la réponsejson: si la réponse est JSON, parsée automatiquementcookies: cookies reçuselapsed: temps écoulé
Toujours regarder la doc du module (ansible-doc <fqcn>) pour connaître les champs exposés.
set_fact:, créer une variable au runtime
Section intitulée « set_fact:, créer une variable au runtime »- name: Calculer un identifiant à partir de plusieurs sources ansible.builtin.set_fact: server_id: "{{ inventory_hostname | upper }}-{{ ansible_default_ipv4.address | replace('.', '-') }}"
- name: Utiliser server_id ansible.builtin.debug: msg: "Server ID = {{ server_id }}"set_fact: crée une variable de play disponible dans toutes les tâches suivantes. Elle est précédence niveau 19, gagne sur le vars: du play (12) mais pas sur --extra-vars (22).
Plusieurs facts dans un même set_fact: :
- name: Plusieurs facts ansible.builtin.set_fact: server_id: "{{ inventory_hostname | upper }}" deploy_date: "{{ ansible_date_time.iso8601 }}" deploy_user: "{{ ansible_user_id }}"La portée d'un set_fact:
Section intitulée « La portée d'un set_fact: »Par défaut, un set_fact: est éphémère : disponible dans le play courant, perdu au prochain run. Avec cacheable: true, il est stocké dans le fact_caching :
- name: Set_fact persistant ansible.builtin.set_fact: last_deploy_date: "{{ ansible_date_time.iso8601 }}" cacheable: trueAu prochain run sur le même hôte, last_deploy_date est automatiquement chargé depuis le cache avant la phase gather_facts. Vous pouvez l'utiliser pour comparer des dates.
Configuration du fact_caching dans ansible.cfg :
[defaults]fact_caching = jsonfilefact_caching_connection = ./.ansible_factsfact_caching_timeout = 7200 # 2hBackends supportés : jsonfile (fichiers locaux), redis (recommandé production), memcached.
Cas pratique, chaîner register puis set_fact
Section intitulée « Cas pratique, chaîner register puis set_fact »Voici l'exemple validé sur le lab ecrire-code-register-set-fact :
---- name: Challenge register set_fact hosts: db1.lab become: true
tasks: - name: Hostname ansible.builtin.command: hostname -s register: hostname_result changed_when: false
- name: Kernel ansible.builtin.command: uname -r register: kernel_result changed_when: false
- name: Construire system_id ansible.builtin.set_fact: system_id: "{{ hostname_result.stdout }}:{{ kernel_result.stdout }}"
- name: Poser le fichier ansible.builtin.copy: dest: /tmp/system-id.txt content: "system_id={{ system_id }}\n" mode: "0644"Contenu de /tmp/system-id.txt sur db1.lab :
system_id=db1:5.14.0-628.el10.x86_64Pattern : deux command registered, un set_fact qui combine, une tâche qui consomme la variable créée.
changed_when: false sur les commandes de lecture
Section intitulée « changed_when: false sur les commandes de lecture »Une commande comme hostname -s ne modifie pas l'état du système, pourtant le module command la marque par défaut comme changed=true, ce qui pollue le PLAY RECAP et peut déclencher des handlers à tort.
Toujours poser changed_when: false sur une commande de lecture :
- name: Lire le hostname (lecture pure, pas de modif) ansible.builtin.command: hostname -s register: hostname_result changed_when: false # ← ne marque pas comme changed check_mode: false # ← exécute même en --check (pour avoir la vraie valeur)Combiné à check_mode: false, vous obtenez la valeur réelle même quand le playbook tourne en --check.
until: pour attendre une condition
Section intitulée « until: pour attendre une condition »Couplé avec register:, until: répète une tâche jusqu'à ce qu'une condition soit vraie :
- name: Attendre que le service réponde ansible.builtin.uri: url: http://localhost/health status_code: 200 register: health_check until: health_check.status == 200 retries: 30 delay: 2 # 30 retries × 2s = 60s d'attente maxTrès utile après un démarrage de service ou un déploiement, la tâche échoue après le timeout total si la condition n'est jamais vraie.
failed_when: et changed_when:
Section intitulée « failed_when: et changed_when: »Avec register:, vous pouvez redéfinir quand une tâche est considérée failed ou changed :
- name: Lancer un script qui retourne 0 ou 1 selon l'état ansible.builtin.command: /usr/local/bin/check-state.sh register: state_result failed_when: state_result.rc not in [0, 1] # rc=2 = vraiment failed changed_when: state_result.rc == 1 # rc=1 = changement détectéPermet d'utiliser command: ou shell: de façon idempotente en mappant les codes retour sur la sémantique Ansible.
Pièges fréquents
Section intitulée « Pièges fréquents »| Symptôme | Cause | Fix |
|---|---|---|
'dict object' has no attribute 'stdout' | La tâche a échoué avant, register n'a pas le champ attendu | when: not result.failed ou failed_when: adapté |
set_fact perdu entre 2 plays | Sans cacheable: true, le fact est limité au play courant | Ajouter cacheable: true (avec attention à la persistence) |
changed=true à chaque run sur un command de lecture | Pas de changed_when: posé | Ajouter changed_when: false |
register: ne capture rien quand la tâche est en --check | command est skippé en check mode | Ajouter check_mode: false sur la tâche |
| Fact persistant qui contient une valeur obsolète | cacheable: true sans expiration | Ajuster fact_caching_timeout ou nettoyer le cache (rm -rf .ansible_facts/) |
Contrôle de connaissances
Section intitulée « Contrôle de connaissances »Vérifiez que l'essentiel de ce guide est acquis. Les questions portent uniquement sur ce qui vient d'être expliqué ici.
Contrôle de connaissances
Validez vos connaissances avec ce quiz interactif
Informations
- Le chronomètre démarre au clic sur Démarrer
- Questions à choix multiples, vrai/faux et réponses courtes
- Vous pouvez naviguer entre les questions
- Les résultats détaillés sont affichés à la fin
Lance le quiz et démarre le chronomètre
Vérification
(0/0)Profil de compétences
Quoi faire maintenant
Ressources pour progresser
Des indices pour retenter votre chance ?
Nouveau quiz complet avec des questions aléatoires
Retravailler uniquement les questions ratées
Retour à la liste des certifications
À retenir
Section intitulée « À retenir »register: varcapture la sortie d'un module ; champs courants :stdout,rc,changed,failed,delta.set_fact:crée une variable de play au runtime ; précédence niveau 19.cacheable: truesur set_fact = fact persistant via fact_caching (jsonfile/redis/memcached).- Sur les commandes de lecture pure : toujours
changed_when: false+check_mode: false. until + retries + delaytransforme une tâche en boucle d'attente conditionnelle.failed_when:etchanged_when:redéfinissent la sémantique Ansible d'un module non-idempotent.
Mettre en pratique
Section intitulée « Mettre en pratique »Capturer une sortie est facile, la réutiliser correctement l'est moins. Le lab vous fait enregistrer le résultat d'un module avec register, l'exploiter dans un when: puis dans un loop:, construire une valeur dérivée avec set_fact, et la rendre persistante avec cacheable: true. Le contrôle relit le fait mis en cache, donc ce qui survit à la fin du play.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Conditions avec when : le résultat capturé sert presque toujours à décider si la tâche suivante s'exécute.
- Boucles avec loop : une tâche
registerplacée dans une boucle range ses résultats dansresults, à parcourir ensuite. - failed_when et changed_when : redéfinir échec et changement à partir du
rcou dustdoutque vous venez de capturer.