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
- bob
In 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: package
Here, 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: user
This 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_item
This 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_user
This 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
loop
is 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
loop
instead ofwith_items
for better performance and consistency. - Be mindful of the performance impact when looping over large datasets.
- Use
loop_control: label
to customize the output of your loops for better readability in Ansible output.