Skip to content

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_backups
when: ansible_facts['os_family'] == 'Debian' or ansible_facts['os_family'] == 'RedHat'
when: not enable_backups

Grouping 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_backups

The 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_backups

Identical 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

combine_demo.yaml
- 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_backups
ok: [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 c
ok: [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 c
skipping: [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 of and.
  • Always use explicit parentheses the moment and and or appear 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.
Last updated on