
Par défaut, si une tâche échoue sur un hôte mais réussit sur les autres, Ansible continue le play sur les hôtes restants. Avec any_errors_fatal: true au niveau du play, dès qu'une tâche échoue sur n'importe quel hôte, le play s'arrête net pour tous les hôtes. C'est l'inverse philosophique d'ignore_errors:, ici on veut une opération atomique sur le cluster : soit toutes les machines sont OK, soit on arrête tout.
C'est l'outil pour les rolling updates stricts ou les migrations cluster où une moitié-réussite est pire qu'un échec total.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- L'effet de
any_errors_fatal: trueau niveau du play - La différence avec
max_fail_percentage: 0 - Cas d'usage : rolling update strict, migration de schéma, opération all-or-nothing
- Combinaison avec
serial:
Prérequis
Section intitulée « Prérequis »- Avoir lu Plays et tasks (notion de play multi-hôtes) ;
- Avoir lu Parallélisme et stratégies (
serial:,max_fail_percentage:).
La syntaxe
Section intitulée « La syntaxe »- name: Migration cluster atomique hosts: webservers any_errors_fatal: true tasks: - name: Tâche critique ansible.builtin.command: /usr/local/bin/migrate.sh changed_when: trueSi migrate.sh échoue sur n'importe quel webserver, le play s'arrête immédiatement, même les hôtes qui ont réussi voient leurs tâches suivantes non exécutées.
Différence avec max_fail_percentage:
Section intitulée « Différence avec max_fail_percentage: »Les deux directives sont liées mais subtilement différentes :
| Directive | Effet |
|---|---|
any_errors_fatal: true | Arrête le play dès la 1ère erreur sur n'importe quel hôte |
max_fail_percentage: 0 | Arrête le play si plus de 0% des hôtes du batch courant ont échoué (= dès la 1ère erreur du batch, pour le batch courant) |
max_fail_percentage: 30 | Arrête si plus de 30% du batch a échoué |
Avec serial:, la nuance compte : max_fail_percentage: 0 arrête seulement le batch courant, any_errors_fatal: true arrête tout immédiatement.
# Rolling update : arrêter dès qu'un hôte échoue, pas continuer sur les autres- name: Déploiement cluster strict hosts: webservers serial: 1 any_errors_fatal: true tasks: - name: Déployer la version cible de l'application ansible.builtin.dnf: name: "app-{{ app_version }}" state: presentSur 5 webservers en serial: 1, si web2 échoue, web3, web4, web5 ne sont pas déployés (au lieu de l'être avec un comportement par défaut).
Cas d'usage
Section intitulée « Cas d'usage »Migration de schéma DB cluster
Section intitulée « Migration de schéma DB cluster »- name: Migrer le schéma sur tous les replica hosts: dbservers any_errors_fatal: true tasks: - name: Lancer la migration ansible.builtin.command: /usr/local/bin/migrate-schema.sh changed_when: trueSi la migration échoue sur un seul replica, vous voulez arrêter immédiatement plutôt que continuer et créer des replica désynchronisés.
Renouvellement de certificats simultané
Section intitulée « Renouvellement de certificats simultané »- name: Renouveler les certificats sur tout le cluster hosts: all any_errors_fatal: true tasks: - name: Lancer certbot ansible.builtin.command: /usr/bin/certbot renew --no-self-upgrade changed_when: trueSi un nœud échoue, on arrête plutôt que de partager des certificats expirant à des moments différents.
Arrêt synchrone de service
Section intitulée « Arrêt synchrone de service »- name: Arrêter un service partout en même temps (maintenance) hosts: webservers any_errors_fatal: true tasks: - name: Stopper le service ansible.builtin.systemd: name: app state: stoppedAvant une maintenance globale, vous voulez soit tout arrêter, soit rien, un état partiel laisse des hôtes inutilisables tandis que d'autres tournent.
Cas pratique, validation syntaxe
Section intitulée « Cas pratique, validation syntaxe »Voici l'exemple validé sur le lab ecrire-code-any-errors-fatal :
- name: Challenge any errors fatal hosts: webservers become: true any_errors_fatal: true tasks: - name: Marqueur sans erreur ansible.builtin.copy: dest: "/tmp/anyfatal-{{ inventory_hostname }}.txt" content: "any_errors_fatal OK\n" mode: "0644"Sans erreur réelle, le play tourne normalement et pose 2 fichiers (web1 + web2). Pour prouver que any_errors_fatal: true arrête tout, il faudrait injecter une erreur, ce qui casserait le test (le play s'arrête en failed).
Le comportement réel se vérifie en injectant volontairement un échec : on observe alors que tous les webservers ont leurs tâches suivantes non exécutées.
any_errors_fatal au niveau task ou block
Section intitulée « any_errors_fatal au niveau task ou block »any_errors_fatal: est une directive de play par défaut. Depuis Ansible 2.7, on peut aussi la poser au niveau block :
- name: Grouper les tâches liées block: - name: Tâche critique 1 ... - name: Tâche critique 2 ... any_errors_fatal: trueEffet : l'échec d'une tâche du block sur n'importe quel hôte arrête le play. Hors du block, le comportement par défaut reprend.
Pièges fréquents
Section intitulée « Pièges fréquents »| Symptôme | Cause | Fix |
|---|---|---|
any_errors_fatal: true au niveau task | Pas supporté | Le mettre au niveau play ou block |
| Play s'arrête trop vite avec une erreur "secondaire" | C'est le comportement attendu | Considérer max_fail_percentage: plus permissif si la tolérance est OK |
Combiné avec ignore_errors: true | ignore_errors: neutralise l'effet | Choisir l'un ou l'autre |
Combiné avec block/rescue | Le rescue peut "capturer" et neutraliser any_errors_fatal | Bien réfléchir à l'interaction |
serial: 1 + any_errors_fatal: true mais le play continue après échec | Vérifier qu'il n'y a pas un block/rescue qui capture | Logiquement, any_errors_fatal doit gagner sauf rescue |
À retenir
Section intitulée « À retenir »any_errors_fatal: trueau niveau play : arrête le play dès la 1ère erreur sur n'importe quel hôte.- Différent de
max_fail_percentage: 0qui agit sur le batch courant (avecserial:). - Cas d'usage : migration cluster atomique, renouvellement de certificats, arrêt synchrone de service.
- Combiné avec
serial:strict : un seul échec arrête tout le rolling update. - Disponible aussi au niveau block depuis Ansible 2.7.
Mettre en pratique
Section intitulée « Mettre en pratique »Un arrêt immédiat se juge sur un play réel, pas sur un extrait. Le lab vous fait activer any_errors_fatal: true sur un play multi-hôtes, comparer le résultat au comportement par défaut puis à max_fail_percentage, et observer ce que donne la combinaison avec serial:. La validation porte sur l'état des hôtes à la fin du play, donc sur la propagation réelle de l'échec plutôt que sur la syntaxe écrite.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Quiz Écrire du code : 30 questions pour valider tout le bloc « Écrire du code » avant d'attaquer les inventaires.
- Inventaires statiques :
any_errors_fatalraisonne sur un ensemble d'hôtes, et l'inventaire est ce qui le définit. - Patterns d'hôtes : réduire le périmètre d'un play avec
--limitavant de le rendre bloquant à la moindre erreur.