
Quand une tâche échoue dans un playbook de 100 lignes, relancer tout est lent et frustrant. Ansible fournit un débogueur interactif qui ouvre un REPL Python au moment de l’échec : on inspecte les variables (p task_vars['x']), on modifie les arguments à chaud (task.args['name'] = 'nginx'), on rejoue la tâche modifiée (redo), on continue le playbook (continue). Activable au niveau task ou play avec debugger: on_failed.
Cette page détaille les 6 commandes du REPL, le workflow recommandé pour fixer une variable au runtime, et les 2 cas où ne pas activer le débogueur (CI/CD, AWX/AAP, cron).
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Activer
debugger: on_failedau niveau task ou play. - Inspecter variables, arguments, résultat avec
p. - Modifier les args (
task.args['x'] = 'y') et rejouer avecredo. - Injecter une variable manquante via
task_vars. - Quitter proprement (
continue,quit). - Quand NE PAS utiliser le débogueur (interactif requis).
Prérequis
Section intitulée « Prérequis »- Avoir lu Verbosité Ansible.
- Comprendre les variables et précédence.
Activer le débogueur
Section intitulée « Activer le débogueur »Trois niveaux d’activation, du plus fin au plus large.
Niveau task
Section intitulée « Niveau task »tasks: - name: Tâche fragile ansible.builtin.dnf: name: nginx state: present debugger: on_failed # ← s'active uniquement sur cette tâcheNiveau play
Section intitulée « Niveau play »- hosts: webservers debugger: on_failed # ← s'active sur toutes les tasks de ce play tasks: - ...Globalement (variable d’environnement)
Section intitulée « Globalement (variable d’environnement) »ANSIBLE_ENABLE_TASK_DEBUGGER=True ansible-playbook lab.ymlGranularité : task > play > global. La task gagne en cas de conflit.
Valeurs possibles de debugger:
Section intitulée « Valeurs possibles de debugger: »| Valeur | Effet |
|---|---|
always | Ouvre le REPL après chaque tâche (TDD, très lent) |
never | Désactive (default sauf si globalement activé) |
on_failed | Recommandé — REPL uniquement en cas d’échec |
on_unreachable | REPL uniquement si l’host devient unreachable |
on_skipped | REPL si la tâche est skippée (rare) |
Le REPL au runtime
Section intitulée « Le REPL au runtime »Quand une tâche échoue, vous voyez :
TASK [Installer nginx-impossible] ***fatal: [db1.lab]: FAILED! => {"msg": "...nginx-impossible..."}
[db1.lab] TASK: Installer nginx-impossible (debug)>Le prompt (debug)> indique que vous êtes dans le REPL. Tapez help pour la liste.
Les 6 commandes essentielles
Section intitulée « Les 6 commandes essentielles »| Commande | Effet |
|---|---|
p <expr> | Print Python — ex p task, p task.args, p task_vars['x'], p result._result |
task.args['x'] = 'y' | Modifie un argument de la tâche en mémoire |
task_vars['x'] = 'y' | Injecte une variable dans le scope de la tâche |
update_task (u) | Recrée la tâche avec les nouvelles variables/args |
redo (r) | Rejoue la tâche modifiée |
continue (c) / quit (q) | Continuer / abandonner le playbook |
Workflow type — fix d’un mauvais nom de paquet
Section intitulée « Workflow type — fix d’un mauvais nom de paquet »-
La tâche échoue :
fatal: [db1.lab]: FAILED! => {"msg": "Failed to install: nginx-impossible..."}[db1.lab] TASK: Installer nginx-impossible (debug)> -
Inspecter ce qui a été passé :
(debug)> p task.args{'name': 'nginx-impossible', 'state': 'present'} -
Modifier l’argument :
(debug)> task.args['name'] = 'nginx' -
Rejouer :
(debug)> redochanged: [db1.lab] -
Continuer :
(debug)> continueTASK [Tâche suivante] ***...
🔍 Observation : on a fixé un bug sans modifier le YAML ni relancer le playbook. Sur une fleet de 50 hôtes où une seule tâche plante, c’est inestimable.
Workflow — injecter une variable manquante
Section intitulée « Workflow — injecter une variable manquante »- ansible.builtin.copy: dest: "{{ target_dir }}/file.txt" content: "Hello" mode: "0644"Si target_dir n’est pas défini :
fatal: [db1.lab]: FAILED! => {"msg": "...'target_dir' is undefined..."}[db1.lab] TASK: copy (debug)>Au REPL :
(debug)> p task_vars.get('target_dir', 'undefined')'undefined'(debug)> task_vars['target_dir'] = '/tmp'(debug)> update_task(debug)> redochanged: [db1.lab]🔍 Observation : task_vars['x'] = 'y' injecte la variable, update_task (raccourci u) recrée la tâche avec le nouveau scope, puis redo rejoue. Workflow puissant pour résoudre les undefined variable.
⚠️ strategy: linear mandatory en debug
Section intitulée « ⚠️ strategy: linear mandatory en debug »- hosts: webservers strategy: free # ← DANGER avec le débogueur debugger: on_failedAvec strategy: free, pendant que vous êtes au prompt (debug)> sur web1.lab, les tâches de web2.lab continuent à tourner. Race conditions garanties.
Toujours garder strategy: linear (default) en debug pour avoir une pause synchrone sur tous les hosts.
Quand NE PAS utiliser le débogueur
Section intitulée « Quand NE PAS utiliser le débogueur »Le débogueur est interactif. À ne jamais activer dans :
- CI/CD (GitHub Actions, GitLab CI) : pas de stdin → le pipeline freeze indéfiniment.
- AWX / AAP : les jobs n’ont pas de prompt utilisateur.
- Cron / systemd timers : pareil.
- Production : laisser
debugger: on_faileddans un playbook commit en prod = bombe à retardement.
Pour ces contextes, préférer :
-vvv+ logs détaillés (page Verbosité).ANSIBLE_KEEP_REMOTE_FILES=1+ inspection forensic.ansible-navigator replay <artifact.json>(page EE) pour rejouer un échec sans relancer.
Lab pratique
Section intitulée « Lab pratique »Le lab troubleshooting/debugger (labs/troubleshooting/debugger/) couvre les 6 exercices : activer debugger: on_failed, inspecter les vars, modifier les args, injecter une variable, comprendre strategy: linear vs free. Challenge final : fix d’un target_dir manquant au runtime.
À retenir
Section intitulée « À retenir »debugger: on_failedau niveau task ou play, pas en production.pprint accepte n’importe quelle expression Python (vars, args, result).task.args['x'] = ...+redomodifie un argument et rejoue.task_vars['x'] = ...+update_task+redoinjecte une variable manquante.strategy: linearmandatory en debug (race conditions avecfree).- Jamais de débogueur en CI, AAP, cron, ou prod (interactivité requise).