Aller au contenu
English
English
Infrastructure as Code medium

ignore_errors Ansible : usage légitime vs anti-pattern

75 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

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

6 questions
6 min.
70% requis

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

  • 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 ce site gratuitement, sans publicité, sans profilage et sans compte à créer. 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