Combining Conditions
Real conditions are rarely just one check. This chapter covers combining multiple conditions into a single when: — and a precedence gotcha that can silently produce the wrong answer if you’re not deliberate about it.
and, or, not
Exactly what you’d expect:
when: ansible_facts['os_family'] == 'Debian' and enable_backupswhen: ansible_facts['os_family'] == 'Debian' or ansible_facts['os_family'] == 'RedHat'when: not enable_backupsGrouping With Parentheses
For anything beyond a single and or or, group explicitly:
when: (ansible_facts['os_family'] == 'Debian' or ansible_facts['os_family'] == 'RedHat') and enable_backupsThe List Form Of when: — Implicit AND
Rather than chaining and repeatedly, when: accepts a YAML list — every item must be true for the task to run:
when:
- ansible_facts['os_family'] == 'Debian'
- enable_backupsIdentical in effect to the and version above, and often easier to read once you have more than one or two conditions.
Real-World Example: OS And A Feature Flag
- name: Combining Conditions Demo
hosts: servers
vars:
enable_backups: true
tasks:
- name: Run backup only on Debian hosts with backups enabled
ansible.builtin.debug:
msg: "Backing up..."
when:
- ansible_facts['os_family'] == 'Debian'
- enable_backupsok: [ubuntu] => {
"msg": "Backing up..."
}
skipping: [fedora]fedora skips even though enable_backups is true for both hosts — its os_family fact fails the first condition, and since the list form requires every item to be true, that’s enough to skip the whole task.
A Gotcha: Operator Precedence
and binds tighter than or, exactly as in most programming languages — meaning mixing them without parentheses can quietly evaluate in an order you didn’t intend:
vars:
a: true
b: false
c: false
tasks:
- name: Ambiguous without parentheses
ansible.builtin.debug:
msg: "This runs"
when: a or b and cok: [ubuntu] => {
"msg": "This runs"
}This is read as a or (b and c), not (a or b) and c. b and c is false, but a is true, so the whole thing is true — the task runs. If the actual intent was “(a or b) and c,” this result is silently wrong, since c is false and that version should have skipped the task entirely.
when: (a or b) and cskipping: [ubuntu]Parentheses make the intended grouping explicit, and the result changes completely.
Best Practices
- Prefer the list form of
when:for multiple AND-ed conditions — it reads more clearly than a long chain ofand. - Always use explicit parentheses the moment
andandorappear in the same condition — never rely on remembering which one binds tighter. - If a
when:condition is getting hard to read, consider computing the logic into a variable ahead of time instead of cramming it all into one line at the point of use.