One playbook must handle different OSes, environments and lists of users, packages or sites.
when takes a raw Jinja2 expression (no {{ }}) evaluated per host:
when: ansible_facts['os_family'] == "Debian"when: result.rc != 0,when: feature_enabled | bool- A list means all must be true:
when: [a, b].
Since ansible-core 2.19, conditionals must evaluate to an actual boolean. A bare string variable like when: some_var where some_var is "yes" is an error; convert explicitly with | bool or compare with == "yes".
loop repeats a task over a list; the current item is item:
loop: [nginx, git, htop]- over a list of dicts:
item.name,item.groups - over a dict:
loop: "{{ users | dict2items }}"givesitem.keyanditem.value - nested data:
subelements, orproductfor combinations.
loop_control refines it: label: "{{ item.name }}" keeps output readable, loop_var: user avoids clashes in nested includes, pause waits between iterations.
when is evaluated per item when combined with loop, so you can skip some items. Registering a looped task gives result.results, a list with one entry per item.
Many modules accept a list directly (apt: name: [nginx, git]), which is faster than looping because it runs once.
Example
- name: Users and packages
hosts: localhost
connection: local
vars:
users:
- {name: ana, admin: true}
- {name: bo, admin: false}
features: {gzip: "yes", http3: "no"}
tasks:
- name: Show admins only
ansible.builtin.debug:
msg: "{{ item.name }} is an admin"
loop: "{{ users }}"
loop_control: {label: "{{ item.name }}"}
when: item.admin
- name: Enabled features
ansible.builtin.debug:
msg: "feature {{ item.key }} on"
loop: "{{ features | dict2items }}"
when: item.value | bool # explicit boolean conversion
# ok: [localhost] => (item=ana) => msg: ana is an admin
# skipping: [localhost] => (item=bo)Remember
- when is raw Jinja2 and must yield a real boolean
- loop with item; dict2items for dicts; loop_control label
- Pass lists directly to modules that accept them
Watch out for
- Wrapping when expressions in {{ }}, which triggers warnings and can break evaluation.