Ansible Loops and loop_control
One task with a loop replaces five near-identical tasks, and the loop is where playbooks stop being scripts. This covers a plain list, a list of dictionaries, looping over what a previous loop registered, the `label` that stops the output becoming unreadable, and `until`/`retries` for something that is not ready yet.
Plays and Playbooks Guide 13 of 45 Intermediate
- OSUbuntu 26.04 LTS
- ansible-core2.20.1
- Python3.14.4
- TimeAbout 16 min
- Reviewed23 August 2026
Written against the versions above. `loop:` is the current keyword. `with_items` and the other `with_*` forms still work and are not slated for removal, but they are no longer recommended and every current example uses `loop`. Where `with_items` flattened nested lists automatically, `loop` does not - use the `flatten` filter if you need that.
| Server Name | IP Address | OS | Roles | CPU | RAM | HDD |
|---|---|---|---|---|---|---|
| ANS-CTL01 | 192.168.0.36 | Ubuntu 26.04 LTS | Ansible Control Node | 2 Core | 3 GB | 50 GB |
| ANS-A01 | 192.168.0.37 | Ubuntu 26.04 LTS | Managed Node (group: web) | 2 Core | 3 GB | 50 GB |
Before you start
- A control node configured as shown in the first step.
- The session creates directories under
/opt/loopdemo, two service accounts, and a file that appears six seconds late. All are removed at the end.
-
The configuration this guide assumes
-
A loop over a list
-
A loop over dictionaries
-
Looping over what you registered
-
Retrying until something is true