Ansible Loops

Ansible offers powerful looping mechanisms that can significantly enhance your playbooks’ efficiency and readability. In this blog post, we’ll dive deep into Ansible loops, exploring various elements and providing practical examples to help you master this essential feature.
Table of Contents
- Introduction to Loops
- Basic Loop Usage
- loop_control and loop_var
- Looping Over Dictionaries
- Nested Loops
- Using Loops with Include Statements
- Advanced Loop Techniques
- Best Practices and Tips
Introduction to Loops
Loops in Ansible allow you to repeat a task multiple times with different input values. This can dramatically reduce the amount of code you need to write and maintain, making your playbooks more efficient and easier to read.
Basic Loop Usage
The most common way to use loops in Ansible is with the loop keyword. Here’s a simple example:
- name: Ensure multiple users exist
ansible.builtin.user:
name: "{{ item }}"
state: present
loop:
- john
- jane
- bobIn this example, the task will run three times, creating users named john, jane, and bob. The loop variable item takes on each value in the list.
loop_control and loop_var
The loop_control directive allows you to fine-tune how your loops behave. One of its most useful features is loop_var, which lets you rename the loop variable:
- name: Install multiple packages
ansible.builtin.apt:
name: "{{ package }}"
state: present
loop:
- nginx
- postgres
- redis
loop_control:
loop_var: packageHere, we’ve used loop_var: package to rename the loop variable from item to package, making the playbook more readable.
Looping Over Dictionaries
Loops become even more powerful when working with dictionaries:
- name: Create multiple users with specific properties
ansible.builtin.user:
name: "{{ user.name }}"
groups: "{{ user.groups }}"
state: present
loop:
- { name: 'john', groups: 'admins' }
- { name: 'jane', groups: 'developers' }
- { name: 'bob', groups: 'support' }
loop_control:
loop_var: userThis example demonstrates how to loop over a list of dictionaries, creating users with specific properties.
Nested Loops
Ansible supports nested loops, allowing you to iterate over multiple lists:
---
# sample-loop.yml
- name: Print outer and inner items
ansible.builtin.debug:
msg: "outer item={{ outer_item }} inner item={{ item }}"
loop:
- a
- b
- c
- include_tasks: sample-loop.yml loop:
- 1
- 2
- 3
loop_control:
loop_var: outer_itemThis loops through two loops
ok: [localhost] => (item=a) => {
"msg": "outer item=1 inner item=a"
}
ok: [localhost] => (item=b) => {
"msg": "outer item=1 inner item=b"
}
ok: [localhost] => (item=c) => {
"msg": "outer item=1 inner item=c"
}
ok: [localhost] => (item=a) => {
"msg": "outer item=2 inner item=a"
}
ok: [localhost] => (item=b) => {
"msg": "outer item=2 inner item=b"
}
ok: [localhost] => (item=c) => {
"msg": "outer item=2 inner item=c"
}
ok: [localhost] => (item=a) => {
"msg": "outer item=3 inner item=a"
}
ok: [localhost] => (item=b) => {
"msg": "outer item=3 inner item=b"
}
ok: [localhost] => (item=c) => {
"msg": "outer item=3 inner item=c"
}Using Loops with Include Statements
Loops can be used with include_tasks to dynamically include task files:
- name: Include task file for each user
include_tasks: user_setup.yml
loop:
- { name: 'john', role: 'admin' }
- { name: 'jane', role: 'developer' }
loop_control:
loop_var: current_userThis includes and executes the user_setup.yml task file for each user in the loop.
Advanced Loop Techniques
Ansible offers several advanced looping techniques:
- with_items: An older syntax, still supported but
loopis preferred. - with_dict: For iterating over dictionary key-value pairs.
- with_fileglob: For looping over files matching a pattern.
- with_sequence: For generating a sequence of items to iterate over.
Example of with_sequence:
- name: Create multiple directories
ansible.builtin.file:
path: "/tmp/dir{{ item }}"
state: directory
with_sequence: start=1 end=5 format="%02d"This creates directories named dir01 through dir05.
Best Practices and Tips
- Use meaningful names for your loop variables with
loop_var. - Keep your loops simple and readable. If a loop becomes too complex, consider breaking it into separate tasks.
- Use
loopinstead ofwith_itemsfor better performance and consistency. - Be mindful of the performance impact when looping over large datasets.
- Use
loop_control: labelto customize the output of your loops for better readability in Ansible output.
