Aller au contenu
Infrastructure as Code medium

ignore_errors Ansible : usage légitime vs anti-pattern

65 min de lecture

Logo Ansible

ignore_errors: true indique à Ansible de ne pas considérer une tâche en échec comme bloquante, le play continue malgré l'erreur. C'est une directive simple à utiliser mais souvent un anti-pattern : elle masque les vraies erreurs, rend le diagnostic difficile, et peut laisser un système dans un état incohérent. Cette page liste les rares cas légitimes d'usage, et explique pourquoi failed_when: ou block/rescue/always sont presque toujours préférés.

ansible-lint profil production signale les ignore_errors: true comme problème (ignore-errors), sauf certaines exceptions documentées.

  • L'effet de ignore_errors: true (la tâche échouée est marquée ignored, le play continue)
  • Les 3 cas légitimes où c'est justifié
  • Pourquoi failed_when: est souvent une meilleure réponse
  • Pourquoi block/rescue/always est presque toujours plus propre
  • L'impact dans le PLAY RECAP : ignored=N
- name: Tâche qui échoue
ansible.builtin.command: /bin/false
ignore_errors: true
changed_when: false
- name: Tâche suivante (s'exécute quand même)
ansible.builtin.debug:
msg: "Le play continue"

PLAY RECAP : ok=1 changed=1 failed=0 ignored=1. La tâche en échec est marquée ignored=1 (visible dans le RECAP), le play continue.

Une opération de cleanup où l'échec n'est pas critique :

- name: Tenter de stopper un service (peut ne pas exister)
ansible.builtin.systemd:
name: legacy-service
state: stopped
ignore_errors: true

Si le service n'existe pas, on s'en fiche, c'est exactement ce qu'on voulait. Mais mieux :

# ✅ Plus propre avec failed_when:
- name: Tenter de stopper un service legacy
ansible.builtin.systemd:
name: legacy-service
state: stopped
failed_when: false

failed_when: false est explicite : "ne jamais marquer cette tâche comme failed".

Vérifier la présence d'un binaire pour conditionner les tâches suivantes :

- name: Vérifier la présence de docker
ansible.builtin.command: which docker
register: docker_check
ignore_errors: true
changed_when: false
- name: Configurer Docker (si présent)
ansible.builtin.copy:
src: daemon.json
dest: /etc/docker/daemon.json
mode: "0644"
when: docker_check.rc == 0

Mieux : failed_when: false ou block/rescue :

# ✅ failed_when: false plus explicite
- name: Vérifier la présence de docker
ansible.builtin.command: which docker
register: docker_check
changed_when: false
failed_when: false

Cas 3, Opération attendue d'échouer dans un block/rescue

Section intitulée « Cas 3, Opération attendue d'échouer dans un block/rescue »

Très rarement utile, car block/rescue capture déjà les erreurs proprement :

- name: Grouper les tâches liées
block:
- name: Tenter une opération
ansible.builtin.command: /usr/local/bin/risky.sh
ignore_errors: true # ← inutile dans un block
changed_when: true
rescue:
- name: Cleanup
ansible.builtin.debug:
msg: "Erreur capturée"

ignore_errors: à l'intérieur d'un block empêche le rescue de se déclencher (puisque la tâche n'est plus marquée failed). À éviter.

Trois raisons :

  1. Masque les vraies erreurs : un échec inattendu ne lève plus la main. Le bug se manifeste plus tard, ailleurs, sans contexte.

  2. Pollue le diagnostic : un ignored=12 dans le PLAY RECAP est inutilement alarmant, vous devez chercher dans les logs lesquelles ont vraiment échoué.

  3. Empêche block/rescue : si vous mettez ignore_errors: true dans un block, le rescue n'est jamais déclenché. Vous perdez le bénéfice de la gestion structurée.

Voici l'exemple validé sur le lab ecrire-code-ignore-errors :

- name: Challenge ignore errors
hosts: db1.lab
become: true
tasks:
- name: Stopper un service inexistant
ansible.builtin.systemd:
name: ce-service-nexiste-pas
state: stopped
ignore_errors: true
- name: Marqueur post ignore
ansible.builtin.copy:
dest: /tmp/ignore-after.txt
content: "play continued\n"
mode: "0644"

PLAY RECAP : ok=1 changed=1 failed=0 ignored=1. La tâche suivante s'est bien exécutée.

Réécriture préférée sans ignore_errors: :

- name: Stopper un service legacy si présent
ansible.builtin.systemd:
name: ce-service-nexiste-pas
state: stopped
failed_when: false # ← explicite, pas de "ignored" dans RECAP
MécanismeAvantageInconvénient
ignore_errors: trueSimple à écrireMasque les erreurs ; pollue PLAY RECAP
failed_when: falseExplicite : "jamais d'échec"À utiliser avec parcimonie aussi
failed_when: <expr>Précis : on définit ce qui constitue un échecPlus verbeux
block / rescue / alwaysCapture + réagit (notification, cleanup)Plus de structure

Règle pratique : si vous écrivez ignore_errors: true, demandez-vous d'abord si l'une des 3 alternatives ne ferait pas mieux. Dans 99 % des cas, oui.

SymptômeCauseFix
ignored=N dans PLAY RECAP, on ne sait pas quoi a échouéC'est par designPréférer failed_when: ou block/rescue qui montrent le détail
ignore_errors: true dans un block, le rescue ne se déclenche pasC'est attenduRetirer ignore_errors: ; laisser le rescue capturer
ansible-lint signale ignore-errorsAnti-pattern détectéMigrer vers failed_when: ou block/rescue
ignore_errors: true cumulé avec failed_when:Comportement ambiguChoisir l'un ou l'autre, pas les deux
  • ignore_errors: true marque la tâche ignored=1 mais ne fait pas planter le play.
  • 3 cas légitimes, mais dans 99 % des cas, failed_when: ou block/rescue sont préférés.
  • failed_when: false est plus explicite que ignore_errors: true pour "ne jamais échouer".
  • ignore_errors: true dans un block empêche le rescue, anti-pattern.
  • ansible-lint profil production signale ignore-errors comme un problème.

L'effet réel de cette directive se lit dans le PLAY RECAP, pas dans une définition. Le lab vous fait mesurer ce que ignore_errors: true produit sur les compteurs, identifier les rares situations où il se justifie, puis réécrire le même besoin avec failed_when et avec block/rescue. Vous constatez au passage qu'un ignore_errors posé dans un block empêche le rescue de se déclencher.

  • Templates Jinja2 : générer des fichiers de configuration complets plutôt que de les rafistoler ligne à ligne.
  • Module template : l'option validate refuse une configuration invalide avant écriture, ce qui évite l'erreur au lieu de l'ignorer.
  • Quiz Écrire du code : 30 questions pour valider votre maîtrise de la gestion d'erreurs.

Ce site vous est utile ?

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

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn