
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" mode: "0644" 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 »- name: Installer et démarrer le service sur les distributions RedHat when: ansible_os_family == "RedHat" block: - name: Tâche A (RedHat only) ansible.builtin.dnf: name: foo
- name: Tâche B (RedHat only) ansible.builtin.systemd: name: foo state: startedLe 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
Section intitulée « Cas pratique, 4 conditions ciblées »Voici l'exemple validé sur le lab 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 | int ou | string selon besoin |
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 | bool : when: var | bool |
not item.enabled fait planter quand enabled est absent | Accès à clé inexistante | Utiliser not item.enabled | default(false) |
À 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.
Mettre en pratique
Section intitulée « Mettre en pratique »Une condition fausse ne se voit pas dans le code, elle se voit dans le PLAY RECAP. Le lab vous fait conditionner des tâches sur un fact collecté, combiner plusieurs critères dans une liste, tester la présence d'une variable optionnelle avec is defined, et diagnostiquer un when: qui matche à tort. La validation porte sur les tâches réellement passées en skipped, pas sur l'expression écrite.
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Block / rescue / always : une condition posée sur un
blocks'applique à toutes ses tâches, c'est la façon la plus économique de conditionner un groupe. - failed_when et changed_when : la même syntaxe d'expression sert à redéfinir le succès et le changement d'une tâche.
- Tests Jinja2 : le catalogue complet des tests
is defined,is noneouis mappingqui alimentent vos conditions.