Aller au contenu
Infrastructure as Code medium

Check mode et diff Ansible : dry-run et visualisation des changements

10 min de lecture

Logo Ansible

Le check mode Ansible (--check) exécute un playbook en dry-run : il calcule ce qui changerait sans rien modifier. Couplé au mode --diff, vous voyez exactement les diffs des fichiers qui seraient écrits, les paquets qui seraient installés, les services qui seraient démarrés. C’est l’outil de pré-validation indispensable avant toute modification en production, et c’est aussi l’audit de conformité d’une fleet : --check retourne un PLAY RECAP avec changed=N qui chiffre la dérive.

Cette page couvre les deux flags (--check, --diff), leur combinaison, le contrôle au niveau task (check_mode: true|false), et les modules qui ne supportent pas check_mode (command, shell, certains modules custom).

  • --check : exécuter un playbook en dry-run sans rien modifier ;
  • --diff : afficher les diffs des fichiers, configurations, états ;
  • La combinaison --check --diff pour audit complet ;
  • check_mode: true|false au niveau task pour des cas particuliers ;
  • Les modules qui ne supportent pas --check (et comment les gérer).

Lancez un playbook en dry-run :

Fenêtre de terminal
ansible-playbook site.yml --check

Ansible exécute chaque tâche en mode simulation : aucun fichier n’est écrit, aucun paquet installé, aucun service démarré. Le PLAY RECAP affiche les changed=N comme si vous aviez vraiment exécuté.

Sortie typique :

TASK [Installer nginx] ***********************************************
changed: [web1.lab]
changed: [web2.lab]
PLAY RECAP ***********************************************************
web1.lab : ok=5 changed=3 unreachable=0 failed=0
web2.lab : ok=5 changed=3 unreachable=0 failed=0

changed=3 veut dire : 3 tâches modifieraient l’état réel si le playbook tournait pour de vrai. C’est l’indicateur de dérive : sur une fleet conforme, vous attendez changed=0 partout.

--diff affiche le détail des modifications — particulièrement utile pour les modules qui touchent des fichiers (copy, template, lineinfile) :

Fenêtre de terminal
ansible-playbook site.yml --diff

Sortie typique :

TASK [Mettre à jour nginx.conf] ***************************************
--- before: /etc/nginx/nginx.conf
+++ after: /tmp/.ansible/tmp/<sha>/source
@@ -3,7 +3,7 @@
worker_processes auto;
events {
- worker_connections 768;
+ worker_connections 1024;
}
changed: [web1.lab]

Vous voyez exactement ce qui va changer dans le fichier. Indispensable pour valider un changement de config avant de l’appliquer.

C’est la commande d’audit qu’on lance avant tout déploiement risqué :

Fenêtre de terminal
ansible-playbook site.yml --check --diff

Effets combinés :

  • Aucun changement réel sur les managed nodes (--check) ;
  • Affichage complet des diffs (--diff) ;
  • PLAY RECAP avec les changed=N qui montrent ce qui aurait été modifié.

Workflow typique :

Fenêtre de terminal
# 1. Audit dry-run
ansible-playbook site.yml --check --diff > audit.log
# 2. Lecture de l'audit, validation
less audit.log
# 3. Si OK, exécution réelle
ansible-playbook site.yml --diff

Vous pouvez forcer un comportement spécifique sur une tâche, indépendamment du flag CLI :

Une tâche qui doit toujours s’exécuter, même en --check :

- name: Vérifier la version installée
ansible.builtin.command: nginx -v
register: nginx_version
check_mode: false # exécute même en --check
changed_when: false # ne marque pas comme changed

Cas typique : une vérification non-destructive qui doit donner la valeur réelle pour conditionner les tâches suivantes (when: nginx_version.stdout is defined).

Une tâche qui ne doit jamais modifier, même en exécution réelle :

- name: Tester ce que ferait dnf upgrade (toujours simulé)
ansible.builtin.dnf:
name: "*"
state: latest
check_mode: true # toujours en mode simulation
register: upgrade_simulation

Cas typique : afficher la liste des paquets qui seraient mis à jour, sans jamais les mettre à jour.

Tous les modules ne savent pas tourner en check mode. Les principaux non supportés :

ModulePourquoi
command, shell, raw, scriptExécutent une commande arbitraire — Ansible ne peut pas savoir si elle modifie l’état
metaMéta-actions (flush_handlers, clear_facts)
Certains modules customSi le développeur n’a pas implémenté supports_check_mode = True

Pour les modules command/shell, en mode --check ils sont skippés par défaut. Si vous voulez quand même les exécuter (cas d’une vérification non destructive), forcez avec check_mode: false :

- name: Vérifier la version (exécuté même en --check)
ansible.builtin.command: nginx -v
register: result
check_mode: false
changed_when: false

Pour vérifier si un module supporte le check mode :

Fenêtre de terminal
ansible-doc ansible.builtin.dnf | grep -A1 "support_check_mode"

Sur une fleet existante, vous voulez savoir quels hôtes dévient de l’état désiré. Lancez votre playbook de baseline en --check :

Fenêtre de terminal
ansible-playbook baseline.yml --check

Le PLAY RECAP montre les hôtes en dérive :

web1.lab : ok=12 changed=0 unreachable=0 failed=0 ← OK
web2.lab : ok=9 changed=3 unreachable=0 failed=0 ← 3 tâches en dérive
db1.lab : ok=10 changed=2 unreachable=0 failed=0 ← 2 tâches en dérive

Couplé à un script qui parse la sortie et alerte un système de ticketing, c’est un audit de conformité automatisé — pattern fréquent en production grande échelle.

SymptômeCauseFix
--check affiche changed mais une exécution réelle ne change rienModule qui ne supporte pas check correctement (faux positif)Vérifier le module ; tester avec ansible-doc <module>
--check --diff ne montre pas le diffLe module ne capture pas avant/aprèsModule limité ; vérifier en réel avec --diff seul
Une tâche command skippée bloque la suiteMode --check skip command ; les tâches qui dépendent d’un register: plantentForcer check_mode: false sur la tâche command
Diff énorme et illisibleLe module copie un binaire ou un fichier très volumineuxno_log: true pour masquer, ou désactiver --diff ponctuellement
--check modifie quand même quelque choseBug dans un module customReporter le bug ; entretemps check_mode: false à éviter
  • --check lance le playbook en dry-run : aucun changement réel.
  • --diff affiche les diffs des fichiers modifiés (avant/après).
  • --check --diff est la commande d’audit : zéro changement, diff complet.
  • check_mode: false force une tâche à s’exécuter même en --check (vérifications non-destructives).
  • check_mode: true force une tâche à toujours simuler (jamais exécuter).
  • Les modules command et shell sont skippés en --check par défaut — ajouter check_mode: false si lecture sans effet de bord.

Cette page a un lab d’accompagnement : labs/ecrire-code/checkmode-diff/ dans stephrobert/ansible-training. Il contient un README.md guidé, un Makefile (make verify lance les tests), et un challenge final auto-évalué : valider un changement de fichier en —check —diff avant de l’appliquer pour de vrai.

Une fois le lab provisionné :

Fenêtre de terminal
cd ~/Projets/ansible-training/labs/ecrire-code/checkmode-diff/
cat README.md # tuto pas à pas
cat challenge/README.md # consigne du challenge final
pytest -v challenge/tests/ # lancer les tests testinfra

Si les tests passent, vous maîtrisez les concepts couverts dans ce guide. En cas de blocage, docs/troubleshooting.md à la racine du repo couvre les pièges fréquents (rate-limit SSH, clé absente, collection manquante).

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracing. Aujourd'hui, ce site ne couvre même pas mes frais d'hébergement, d'électricité, de matériel, de logiciels, mais surtout de cafés.

Un soutien régulier, même symbolique, m'aide à garder ces ressources gratuites et à continuer de produire des guides de qualité. Merci pour votre appui.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn