
when: est la directive Ansible qui conditionne l’exécution d’une tâche, d’un block ou d’un rôle sur une expression Jinja2. Si l’expression est vraie, la tâche s’exécute ; sinon elle est marquée skipped dans le PLAY RECAP. Cette page couvre la syntaxe correcte (sans {{ }} ni quotes), les opérateurs de comparaison, les multi-conditions via liste (and implicite), les tests Jinja (is defined, is none, is mapping), et les pièges classiques.
C’est la directive la plus utilisée pour adapter un playbook à différentes distributions, environnements ou variables optionnelles.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- La syntaxe de
when:— pas de{{ }}, pas de quotes - Les opérateurs de comparaison :
==,!=,>,<,>=,<=,in,not in - Multi-conditions via liste (
andimplicite) ou expression (and,or,not) - Les tests Jinja :
is defined,is undefined,is none,is mapping,is sequence when:sur un block : applique la condition à toutes les tâches du block
Prérequis
Section intitulée « Prérequis »- Avoir lu Variables — déclaration et Facts et magic vars (les conditions s’appuient sur variables et facts).
La syntaxe correcte
Section intitulée « La syntaxe correcte »- name: Installer nginx uniquement sur RedHat ansible.builtin.dnf: name: nginx when: ansible_os_family == "RedHat"3 règles importantes sur when: :
-
Pas de
{{ }}:when:accepte directement une expression Jinja, pas une interpolation.when: ansible_os_family == "RedHat" # ✅when: "{{ ansible_os_family == 'RedHat' }}" # ❌ erreur, double évaluation -
Pas de quotes externes sauf si l’expression contient des caractères ambigus :
when: var == 1 # ✅when: "var == 1" # ✅ aussi OKwhen: var: var == 1 # ❌ deux-points cassent le YAML -
Une string non vide est truthy :
when: my_varest vrai simy_varest défini ET non vide/zéro/false.
Opérateurs de comparaison
Section intitulée « Opérateurs de comparaison »when: ansible_distribution == "AlmaLinux"when: ansible_distribution != "Ubuntu"when: ansible_distribution_major_version | int >= 10when: ansible_memtotal_mb < 2048when: "'docker' in ansible_facts.packages"when: env not in ["dev", "staging"]Le filtre | int ou | float est nécessaire quand le fact est une string (la plupart des ansible_*_version sont des strings).
Multi-conditions via liste
Section intitulée « Multi-conditions via liste »Quand vous avez plusieurs conditions à combiner avec and (cas le plus fréquent), passez une liste :
when: - ansible_distribution == "AlmaLinux" - ansible_distribution_major_version | int >= 10 - ansible_memtotal_mb >= 1024Toutes les conditions doivent être vraies pour que la tâche s’exécute. C’est plus lisible qu’une longue expression and.
Pour or ou des combinaisons mixtes, écrivez l’expression complète sur une ligne :
when: ansible_distribution == "AlmaLinux" or ansible_distribution == "RHEL"when: (env == "prod" and not maintenance_mode) or force_run | default(false)Les tests Jinja
Section intitulée « Les tests Jinja »Les tests Jinja sont écrits avec is :
| Test | Vrai si… |
|---|---|
var is defined | La variable existe |
var is undefined | Elle n’existe pas |
var is none | Elle est None/null |
var is mapping | C’est un dict |
var is sequence | C’est une liste |
var is iterable | Itérable (liste, dict, string) |
var is string | C’est une string |
var is number | C’est un nombre |
var is regex | C’est un objet regex |
Cas typique — variable optionnelle :
- name: Activer une feature optionnelle ansible.builtin.copy: dest: /tmp/feature.txt content: "feature ON\n" when: - enable_feature is defined - enable_feature | boolenable_feature is defined évite l’erreur “undefined variable” ; | bool convertit 'true'/'1'/'yes' en vrai booléen.
when: sur un block
Section intitulée « when: sur un block »- block: - name: Tâche A (RedHat only) ansible.builtin.dnf: name: foo
- name: Tâche B (RedHat only) ansible.builtin.systemd: name: foo state: started when: ansible_os_family == "RedHat"Le when: sur le block est propagé à toutes les tâches du block. Plus DRY que de répéter le when: sur chacune.
Cas pratique — 4 conditions ciblées (lab ecrire-code/conditions-when)
Section intitulée « Cas pratique — 4 conditions ciblées (lab ecrire-code/conditions-when) »Voici l’exemple validé sur le lab 19-ecrire-code-conditions-when :
---- name: Challenge conditions when hosts: db1.lab become: true gather_facts: true
tasks: - name: cond-redhat ansible.builtin.copy: dest: /tmp/cond-redhat.txt content: "famille=redhat\n" mode: "0644" when: ansible_os_family == "RedHat"
- name: cond-alma10 ansible.builtin.copy: dest: /tmp/cond-alma10.txt content: "os=AlmaLinux10\n" mode: "0644" when: - ansible_distribution == "AlmaLinux" - ansible_distribution_major_version | int >= 10
- name: cond-feature ansible.builtin.copy: dest: /tmp/cond-feature.txt content: "feature=enabled\n" mode: "0644" when: - enable_feature is defined - enable_feature | bool
- name: cond-debian (NE doit PAS s'exécuter sur AlmaLinux) ansible.builtin.copy: dest: /tmp/cond-debian.txt content: "famille=debian\n" mode: "0644" when: ansible_os_family == "Debian"Lancement avec --extra-vars "enable_feature=true" :
PLAY RECAPdb1.lab : ok=4 changed=3 skipped=1 failed=03 fichiers posés (redhat, alma10, feature), 1 task skipped (debian).
when: + loop: ensemble
Section intitulée « when: + loop: ensemble »when: est évalué à chaque itération de la boucle :
- name: Installer uniquement les paquets activés ansible.builtin.dnf: name: "{{ item.name }}" state: present loop: - { name: nginx, enabled: true } - { name: redis, enabled: false } - { name: postgresql, enabled: true } when: item.enabledredis est skippé pour cette itération uniquement ; les deux autres sont installés.
Pièges fréquents
Section intitulée « Pièges fréquents »| Symptôme | Cause | Fix |
|---|---|---|
when: "{{ var == 'x' }}" ne fonctionne pas | Double évaluation Jinja | Retirer {{ }} : when: var == 'x' |
| Expression compare une string et un int incorrectly | Type mismatch | Filtre ` |
when: sur une variable absente plante | Variable undefined | Préfixer par var is defined and ... |
when: var est faux alors que var: "yes" | 'yes' est une string non vide donc truthy, mais YAML 1.2 ne convertit pas | Utiliser ` |
not item.enabled fait planter quand enabled est absent | Accès à clé inexistante | Utiliser `not item.enabled |
À retenir
Section intitulée « À retenir »when:prend une expression Jinja sans{{ }}ni quotes externes.- Multi-conditions and : passer une liste, plus lisible qu’une expression longue.
is defined+| boolsont les deux outils pour gérer les variables optionnelles proprement.when:sur un block propage la condition à toutes les tâches enfants.- Combiné avec
loop:,when:est évalué à chaque itération.
Pratiquer dans le lab
Section intitulée « Pratiquer dans le lab »Cette page a un lab d’accompagnement : labs/ecrire-code/conditions-when/ dans
stephrobert/ansible-training. Il contient
un README.md guidé, un Makefile (make verify lance les tests), et un
challenge final auto-évalué : conditionner 4 tâches sur ansible_os_family, version, et une variable optionnelle.
Une fois le lab provisionné :
cd ~/Projets/ansible-training/labs/ecrire-code/conditions-when/
cat README.md # tuto pas à pascat challenge/README.md # consigne du challenge finalpytest -v challenge/tests/ # lancer les tests testinfraSi 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).