
Quand un playbook échoue, le message d’erreur Ansible peut paraître impénétrable. En réalité, 80 % des erreurs des débutants tombent dans 10 catégories récurrentes — toujours les mêmes — qui se diagnostiquent en quelques minutes une fois qu’on connaît les bons réflexes. Cette page liste ces 10 erreurs avec symptôme → cause probable → fix immédiat, et finit par le workflow de debug générique (-vvv, ansible-config dump, ansible-inventory --graph) qui résout 95 % des cas restants.
Gardez cette page ouverte pendant vos premiers playbooks — c’est exactement le réflexe que vous aurez plus tard sur une fleet de production quand un cron de nuit casse à 3 h du matin.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Identifier rapidement la catégorie d’erreur à partir du message brut ;
- Corriger chaque cas avec une commande ou une modification ciblée ;
- Lancer le mode verbeux (
-v,-vv,-vvv,-vvvv) pour récupérer les détails utiles ; - Inspecter la configuration active et l’inventaire vu par Ansible avec
ansible-config dumpetansible-inventory --graph; - Prévenir les erreurs structurelles via
ansible-lintetyamllint.
Diagnostic rapide
Section intitulée « Diagnostic rapide »| Symptôme | Catégorie | Cause probable | Fix express |
|---|---|---|---|
Permission denied (publickey) | SSH | Clé publique absente côté managed node | ssh-copy-id ou re-provisionner |
Permissions 0644 for 'id_ed25519' are too open | SSH | Clé privée trop permissive | chmod 0600 ssh/id_ed25519 |
Failed to connect to the host via ssh: Connection timed out | SSH | Firewall, IP fausse, hijacking ~/.ssh/config | ssh -vvv ansible@IP |
Host key verification failed | SSH | known_hosts incohérent (VM recréée) | ssh-keygen -R IP ou host_key_checking = False |
sudo: a password is required | Sudo | NOPASSWD absent côté managed node | Vérifier /etc/sudoers.d/ ou ajouter --ask-become-pass |
MODULE FAILURE: No module named ansible | Python | Python 3 absent côté managed node | Bootstrap via module raw |
MODULE FAILURE: No module named 'firewall' | Collection | Binding Python du module manquant | dnf install python3-firewall |
mapping values are not allowed here | YAML | Indentation incohérente, deux-points dans une string | yamllint + corriger |
Could not match supplied host pattern | Inventaire | Hôte ou groupe inexistant dans l’inventaire | ansible-inventory --graph |
[WARNING]: ansible_python_interpreter discovery | Python | Interpréteur Python ambigu sur l’hôte | Poser ansible_python_interpreter explicitement |
Suivent les sections détaillées pour les cas qui demandent un développement.
1. Permission denied (publickey)
Section intitulée « 1. Permission denied (publickey) »Message complet :
fatal: [web1.lab]: UNREACHABLE! => changed=false msg: 'Failed to connect to the host via ssh: ansible@10.10.20.21: Permission denied (publickey,gssapi-keyex,gssapi-with-mic).' unreachable: trueCauses possibles :
- La clé publique n’a jamais été déposée dans
~/.ssh/authorized_keyscôté managed node. - L’utilisateur Ansible n’est pas celui que vous croyez (
ansible_usermal défini). - La clé privée utilisée par Ansible n’est pas celle qui a été déployée.
- Les permissions de
~/.ssh/(0700) ou~/.ssh/authorized_keys(0600) sont fausses côté managed node.
Diagnostic :
ssh -vvv -i ssh/id_ed25519 ansible@10.10.20.21 2>&1 | grep -E "Authenticating|Offering|Authentications"Vous verrez quelle clé Ansible essaie d’utiliser et quelle réponse le serveur retourne.
Fix :
# Si lab : régénérer le lab proprementmake destroy && make bootstrap && make provision
# Si fleet existante : redéployer la cléssh-copy-id -i ssh/id_ed25519.pub ansible@10.10.20.212. sudo: a password is required
Section intitulée « 2. sudo: a password is required »Message :
fatal: [web1.lab]: FAILED! => changed=false module_stderr: |- sudo: a password is required msg: 'MODULE FAILURE: sudo: a password is required'Cause : votre playbook a become: true mais le compte côté managed node n’a pas de NOPASSWD dans /etc/sudoers.d/. Le cloud-init du lab pose ansible ALL=(ALL) NOPASSWD:ALL automatiquement ; sur une fleet existante, vous devez le poser manuellement.
Fix temporaire : lancer avec --ask-become-pass (ou -K) qui demande le mot de passe sudo une fois :
ansible-playbook site.yml --ask-become-passFix durable : poser un fichier /etc/sudoers.d/ansible côté managed nodes via un premier playbook de bootstrap (qui peut utiliser --ask-become-pass une fois).
3. MODULE FAILURE: No module named
Section intitulée « 3. MODULE FAILURE: No module named »Trois variantes selon ce qui manque :
No module named ansible ou ImportError: No module named 'ansible'
Section intitulée « No module named ansible ou ImportError: No module named 'ansible' »Le Python 3 n’est pas installé sur le managed node, ou n’est pas accessible à Ansible. Sur une image RHEL UBI minimale, par exemple, Python est absent par défaut.
Fix : un play de bootstrap qui utilise le module raw (pas de Python requis) pour installer Python 3, suivi de plays normaux. Cf. la section Bootstrap d’un host sans Python 3.
No module named 'firewall'
Section intitulée « No module named 'firewall' »Le module ansible.posix.firewalld a besoin du binding Python python3-firewall côté cible. Sans lui, l’erreur tombe au runtime malgré firewalld installé.
Fix : ajouter python3-firewall à votre playbook de préparation (déjà fait dans labs/bootstrap/prepare-managed-nodes/playbook.yml).
No module named 'libselinux'
Section intitulée « No module named 'libselinux' »Idem côté SELinux : il faut python3-libselinux côté managed node pour que les modules Ansible respectent le contexte SELinux quand ils créent des fichiers.
4. mapping values are not allowed here (YAML)
Section intitulée « 4. mapping values are not allowed here (YAML) »Message typique :
ERROR! Syntax Error while loading YAML. mapping values are not allowed here
The error appears to be in '/home/bob/Projets/ansible-training/site.yml': line 12, column 19Cause : un deux-points (:) dans une chaîne non quotée, ou une indentation incohérente. C’est le piège YAML n°1.
Exemples de YAML cassé :
- name: Configurer un site: prod # ← le deuxième `:` casse tout- name: "Configurer un site: prod" # ← OK avec quotesFix : lancer yamllint sur le fichier avant ansible-playbook :
yamllint site.ymlEt systématiquement quoter les chaînes qui contiennent :, #, ou commencent par un caractère ambigu (*, &, !, ?, |, >).
5. Could not match supplied host pattern
Section intitulée « 5. Could not match supplied host pattern »Message :
[WARNING]: Could not match supplied host pattern, ignoring: webservrCause : typo sur le nom du groupe ou de l’hôte. Le pattern webservr n’existe pas, Ansible l’ignore silencieusement et finit par ne rien faire.
Diagnostic immédiat :
ansible-inventory --graphAffiche l’arbre exact des groupes et hôtes vus par Ansible. Comparez avec votre commande.
Fix : corriger la typo. Pour éviter le piège, intégrez ansible-inventory --graph dans votre workflow avant d’écrire un nouveau pattern.
6. Failed to connect to the host via ssh: Connection timed out
Section intitulée « 6. Failed to connect to the host via ssh: Connection timed out »Causes possibles :
- Firewall côté managed node (port 22 fermé) ;
- IP dans l’inventaire ne correspond plus à l’hôte (DHCP changé) ;
~/.ssh/configlocal avec unHost 10.*ProxyJump qui hijack la connexion ;- VM éteinte ou crashée.
Diagnostic :
# 1. La VM est-elle up et joignable en ICMP ?ping -c 1 10.10.20.21
# 2. Le port 22 est-il ouvert ?nc -z 10.10.20.21 22 && echo OK || echo BLOCKED
# 3. SSH tente la bonne IP ?ssh -vvv ansible@10.10.20.21 2>&1 | grep "Connecting to"Si la troisième commande affiche une IP différente de 10.10.20.21, votre ~/.ssh/config redirige la connexion (hijacking).
Fix : poser un bloc spécifique dans ~/.ssh/config.d/ qui surcharge le générique :
Host 10.10.20.* ProxyCommand none ProxyJump none IdentityFile ~/Projets/ansible-training/ssh/id_ed25519 User ansible7. [WARNING]: ansible_python_interpreter discovery
Section intitulée « 7. [WARNING]: ansible_python_interpreter discovery »Message :
[WARNING]: Platform linux on host web1.lab is using the discovered Python interpreter at/usr/bin/python3.12, but future installation of another Python interpreter could change themeaning of that path.Cause : Ansible a deviné l’interpréteur Python à utiliser, mais signale que ça pourrait changer si vous installez un autre Python.
Fix : poser explicitement ansible_python_interpreter dans votre inventaire ou variables de groupe :
all: vars: ansible_python_interpreter: /usr/bin/python3.12C’est ce que fait l’inventaire du lab — pas de warning et un comportement déterministe.
Le workflow de debug générique
Section intitulée « Le workflow de debug générique »Quand un message ne suffit pas, augmentez la verbosité :
| Niveau | Effet |
|---|---|
-v | Sortie verbose des modules |
-vv | Détails de connexion, paths résolus |
-vvv | Trace SSH complète (commandes envoyées) |
-vvvv | Verbosité maximale + debug Python sur la cible |
Pour comprendre quelle config Ansible utilise réellement :
ansible-config dump --only-changedListe les paramètres qui diffèrent des défauts, avec leur source (variable d’environnement, fichier ansible.cfg, etc.). Indispensable quand un comportement vous surprend.
Pour comprendre quels hôtes Ansible voit :
ansible-inventory --graph # vue arborescenteansible-inventory --host web1.lab # variables résolues sur un hôteansible-inventory --list --yaml # vue exhaustivePrévenir plutôt que guérir
Section intitulée « Prévenir plutôt que guérir »Trois outils à intégrer dans votre workflow dès le premier playbook :
yamllintsur tous vos fichiers YAML — détecte les indentations cassées et les:non quotés ;ansible-lintsur vos playbooks — détecte les anti-patterns Ansible (modulescommand/shellnon gardés parcreates:, tâches sansname:, modules dépréciés) ;ansible-playbook --check --diffavant la vraie exécution — dry-run + affichage des diffs.
Intégrés en CI, ces trois commandes éliminent 80 % des erreurs structurelles avant qu’elles n’atteignent vos managed nodes.
À retenir
Section intitulée « À retenir »- 80 % des erreurs débutant tombent dans 10 catégories : SSH, sudo, Python, YAML, inventaire, connexion réseau.
- Le réflexe n°1 : augmenter la verbosité avec
-vvvpour voir les détails de connexion SSH. ansible-config dump --only-changed+ansible-inventory --graphrésolvent la majorité des cas où le comportement surprend.yamllint+ansible-lint+--checken CI préviennent les erreurs structurelles avant la production.- Les permissions Unix sur
~/.ssh/(0700) etauthorized_keys(0600) sont strictement requises — OpenSSH refuse silencieusement sinon. - Sur une fleet où Python 3 manque, bootstrappez via le module
rawavant les modules normaux.