Ansible Loop is used to iterate over a list of items and perform tasks multiple times with different values. Loops are helpful when you need to repeat similar actions for multiple items or configurations. There are several loop mechanisms in Ansible, including with_items (deprecated in favor of loop in newer Ansible versions), loop, and with_sequence. I’ll provide an example using loop, which is the recommended way to use loops in newer Ansible versions.
If you want to learn from my premium Ansible course on udemy, do enroll now at a special discounted price.
Table of Contents
Create multiple users using a loop
Suppose you want to create multiple user accounts on a set of remote hosts. You can use a loop to iterate through a list of user names and create those accounts on each host.
---
---
- name: Create User Accounts
hosts: webserver
tasks:
- name: Create User Accounts
become: yes
user:
name: "{{ item }}"
state: absent # absent or present
groups: users
loop:
- user1
- user2
- user3
Creating Multiple Users using Ansible Loop
---
- name: Create User Accounts
hosts: webserver
tasks:
- name: Create User Accounts
become: yes
user:
name: "{{ item }}"
state: absent # absent or present
groups: users
loop:
- user1
- user2
- user3
- In this example, We have a play named “Create User Accounts.”
- We define the list of target hosts in the hosts section (replace target_hosts with your host or group specification).
- The task uses the user module to create user accounts. It specifies a loop with a list of user names: user1, user2, and user3.
- The {{ item }} expression is used to reference the current value in the loop (the current user name being processed).
- When you run this playbook, Ansible will execute the user module three times, once for each user in the list. As a result, it will create the specified user accounts on the target hosts.
Create multiple folders using loop
---
- name: Create Directories for Each Date of the Month
hosts: localhost # You can adjust the host or hosts as needed
gather_facts: false # Disable gathering facts, as it's not needed for this task
tasks:
- name: Create Directories
ansible.builtin.file:
path: "/tmp/test_{{ item }}"
state: directory
loop: "{{ range(1, 10 ) | list }}"
Creating Folders using Ansible Loop
- name: Create Directories for Each Date of the Month
hosts: webserver # You can adjust the host or hosts as needed
gather_facts: false # Disable gathering facts, as it's not needed for this task
tasks:
- name: Create Directories
ansible.builtin.file:
path: "/tmp/test_{{ item }}"
state: touch # absent touch directory etc.
loop: "{{ range(1, 10 ) | list }}"
Ansible with_items and with_sequence
Ansible with_items
You can also use other loop mechanisms like with_items or with_sequence to achieve similar results, but loop is the recommended way in newer Ansible versions for improved readability and consistency.
You can pass a list directly to a parameter for some plugins. Most of the packaging modules, like yum and apt, have this capability. When available, passing the list to a parameter is better than looping over the task. For example
- name: Optimal yum
ansible.builtin.yum:
name: "{{ list_of_packages }}"
state: present
- name: Non-optimal yum, slower and may cause issues with interdependencies
ansible.builtin.yum:
name: "{{ item }}"
state: present
loop: "{{ list_of_packages }}"
Ansible Loop Control
Ansible Loop control refers to a set of options and attributes that allow you to control and customize how loops are executed within Ansible playbooks. Loop control options provide fine-grained control over loop iterations and can be used to adjust the behavior of tasks that involve loops. These options are defined within the loop_control dictionary within a loop in Ansible playbooks.
The key loop control options include:
loop
Specifies the list of items over which the loop iterates.
Example Playbook to loop through output:
---
- name: Example Playbook with Register
hosts: webserver
become: yes
tasks:
- name: install required softwares
package:
name: "{{ item }}"
state: present
loop:
- httpd
- ntp
- wget
- telnet
register: softare_installation_output
- name: show softare_installation_output
debug:
msg: "{{ item.results }}"
loop: "{{ softare_installation_output.results }}"
loop_var
Defines the name of the loop variable that holds the current item in each iteration.
---
- name: Example Playbook with Register
hosts: webserver
become: yes
tasks:
- name: install required softwares
package:
name: "{{ item }}"
state: present
loop:
- httpd
- ntp
- wget
- telnet
register: softare_installation_output
- name: show softare_installation_output
debug:
msg: "{{ software.results }}"
loop: "{{ softare_installation_output.results }}"
loop_control:
loop_var: software
label
Assigns a label to the loop to distinguish it from other loops within the playbook.
---
- name: Example Playbook with Register
hosts: webserver
become: yes
tasks:
- name: install required softwares
package:
name: "{{ item }}"
state: present
loop:
- httpd
- ntp
- wget
- telnet
register: softare_installation_output
- name: show softare_installation_output
debug:
msg: "{{ software.results }}"
loop: "{{ softare_installation_output.results }}"
loop_control:
loop_var: software
label: "software_installation_status"
index_var
Allows you to create a loop variable that keeps track of the current iteration index.
---
- name: Example Playbook with Register
hosts: webserver
become: yes
tasks:
- name: install required softwares
package:
name: "{{ item }}"
state: present
loop:
- httpd
- ntp
- wget
- telnet
register: softare_installation_output
- name: show softare_installation_output
debug:
msg: "item position is : {{ idx }} , {{ software.results }}"
loop: "{{ softare_installation_output.results }}"
loop_control:
loop_var: software
label: "{{ inventory_hostname }}"
index_var: idx
pause
Specifies the duration (in seconds) to pause between iterations of the loop. Useful when you want to keep some wait interval between instaling each software.
---
- name: Example Playbook with Register
hosts: webserver
become: yes
tasks:
- name: install required softwares
package:
name: "{{ item }}"
state: present
loop:
- httpd
- ntp
- wget
- telnet
loop_control:
pause: 5
register: softare_installation_output
- name: show softare_installation_output
debug:
msg: "item position is : {{ idx }} , {{ software.results }}"
loop: "{{ softare_installation_output.results }}"
loop_control:
loop_var: software
label: "{{ inventory_hostname }}"
index_var: idx
pause: 10
until
Defines a condition that, when met, causes the loop to exit early before all items have been processed. Useful in checking if a website is up etc.
Conclusion
These loop control options provide flexibility and control, allowing you to fine-tune loop behavior, handle complex scenarios, and improve the efficiency of playbook execution. Loop control is particularly useful when you need to customize the behavior of loops based on specific requirements in your Ansible playbooks.