Ansible Loop - Table of Content
Using the loop keyword, Ansible allows you to iterate a task over a set of items. Loops can be configured to repeat a task using each item in a list, the contents of each file in a list, a truly random pattern of numbers, or more complex structures. This section discusses basic as well complex loops which perform iteration over a list of items.
The following two keywords are being used inside the loop syntax. They are:
- loop
- with_
Syntax:
- name: add multiple users
user:
name: “{{ item }}”
state: present
group: “”
loop:
-
-
Now we will explore the importance of the loop keyword with different examples and learn how to perform interactions on different tasks.
Ansible Training
- Master Your Craft
- Lifetime LMS & Faculty Access
- 24/7 online expert support
- Real-world & Project Based Learning
Basic or standard loops:
In the standard loop we are going to learn about the interaction on the following.
- Iterating Over a Simple List
- Iterating Over a List of Hashes
- Iterating Over a Dictionary
Iterating over a simple list:
If we have a list of users, files, and so on, we can use a simple list in a loop.
- name: delete multiple files from a location
file:
path: ‘/home/ansible/{{ item }}’
state: absent
loop:
- file1
- file2
Explanation: When we run the playbook in the preceding example, it will first select "file" as input and replace the "item" keyword from the path; once file1 is deleted, it will select "file2" as input and delete "file2."
loop: “{{ list_of_files}}”
We could even pass the list as a parameter to some plugins like yum and apt, etc. Passing the list to a parameter is sometimes preferable to using the loop.
Iteration over a list of hashes:
We occasionally encounter situations in which we must add multiple users to distinct groups rather than a single group. In that case, we have a collection of key-value pairs known as hashes. We can also use the loop to iterate over a list of hashes.
Code:
- name: add multiple users
user:
name: “{{ item.name }}”
state: present
group: “{{item.groups}}”
loop:
- { name: ‘user1’, groups: ‘SRE’ }
- { name: ‘user2’, groups: ‘dbadmin’ }
Explanation: In the preceding example, we have two users who we want to add to different groups. So we mentioned the user name as well as the respective group and defined the name in the task using a key that is item.name and so on. The preceding playbook will add ‘user1' to the ‘SRE' group and ‘user2' to the ‘dbadmin' group.
Iterating over a dictionary:
We could really loop over a dictionary, but we must use the dict2items Dict filter to convert it to a list of items.
Code:
vars:
tag:
Environment: QA
Application: Cart
Another: “{{ doesnotexist | default() }}”
tasks:
- name: create a tag dictionary of non-empty tags to set facts
set_fact:
tags_dict: “{{ (tags_dict|default({{}}))|combine({item.key: item.value})}}”
loop: “{{ tags | dict2items }}”
when: item.value !=””
Explanation: We have been looping through dictionary ‘tags' in the preceding example, and dict2items will first convert the dictionary into a list, as shown below:
- key: Environment
value: Cart
- key: Application
value: Cart
Explore Ansible Sample Resumes Download & Edit, Get Noticed by Top Employers !
Subscribe to our YouTube channel to get new updates..!
Complex loops:
- Iterating Over Nested Lists
- Retrying a Task until a Condition Is Met
- Looping Over Inventory
Iterating Over Nested Lists:
Unless we have a list that is a subset of another list, we have a nested list. To iterate over nested lists, we must use a Jinja2 expression. Let's look at an example where we need to add multiple users to multiple groups. In the example below, we have two users who must be added to both the groups' and 'dbadmin'.
Code:
- name: add multiple users to multiple groups
user:
name: "{{ item[0] }}"
state: present
group: “{{ item[1] }}”
loop: "{{ ['user5', 'user6'] |product(['sre', ‘dbadmin’])|list }}"
Retrying a Task until a Condition Is Met:
In some cases, we must stop the loop when a certain condition is met. To stop a loop, we use the ‘until' keyword, as shown below:
Code:
- shell: ls /root | grep “test”
register: result
until: result.rc == 0
retries: 2
delay: 1
Code Explanation:
In the previous example, the shell module would then run till the return code of the shell module is not 0 or the work has been retried two times with a one-second delay. The play failed in the first snapshot because rc is 1 because there is no file or folder with name test2 in the root folder, however when the playbook was run upon generating that folder inside the root folder, it was allowed to pass.It is entirely dependent on the situation. The default values for retries and delays are three times and five seconds, in both.
Looping Over Inventory
When we have products in an inventory and would like to append over the same inventory or a subgroup of such a inventory, we could use the “groups” variable; however, if we're to iterate on goods that are currently in play, we must use the ‘ansible play batch' variable, as shown below:
Code:
# to show the hosts defined under web servers group in the inventory
- debug:
msg: "{{ item }}"
loop: "{{ groups['webservers'] }}"
# to show all the hosts in the current play
- debug:
msg: "{{ item }}"
loop: "{{ ansible_play_batch }}"
Now we will explore how to add controls to loops.
Adding controls to loops:
- Limit Loop Output
- Pause a Loop
- Track Progress of A Loop
Limit Loop Output:
If we're to restrict the output of the Ansible-playbook, that is creating a lot of output on console, we could use ‘label' ruling in conjunction with the ‘loop control' directive.For instance, we need to support different data centres with the same configuration, and ansible-playbook will output all details with the server's name. However, we would like to maintain our output tidy only want the server's identity to be exhibited as just a console output. Here's another one:
Code:
- name: add multiple users
user:
name: “{{ item.name }}”
state: present
group: “{{item.groups}}”
loop:
- { name: ‘user1’, groups: ‘SRE’ }
- { name: ‘user2’, groups: ‘dbadmin’ }
loop_control:
label: "{{ item.name }}"
Code Explanation: We see an example which is similar to the one used in the explanation of ‘Iterate over a list of hashes,' but with the addition of loop control, and you can see the difference because the output only shows the user's name, not the group name.
Pause a Loop
In some cases, we must wait for the first command to complete before executing the next. With loop control, we use the pause directive. It's the same as using sleep in a programming language like PowerShell.
Code:
- name: pause for 5 secs after each file creation
digital_ocean:
name: "{{ item }}"
state: present
loop:
- file3.txt
- file4.txt
loop_control:
pause: 5
Track Progress of A Loop:
If we want to know how many items have been executed in a loop, we can use the ‘index var' directive in conjunction with the ‘loop control' directive. As an example:
Code:
- name: count the fruits
debug:
msg: "{{ item }} with index {{ my_idx }}"
loop:
- kiwi
- papaya
- pear
loop_control:
index_var: my_id
Conclusion:
It is a tutorial for Ansible Loop. In this we discuss the steps and how to use loop keyword, as well as various examples and code implementations.The loop is readily accessible after Ansible version 2.5 or higher but is suggested to use, but this is not a complete replacement for with look>. The syntax 'with lookup> is still valid. Also it is occasionally preferable to pass the list explicitly to a variable.
Related Articles:
About Author
As a senior technical content writer for HRK tainings, srivalli patchava has a greater understanding of today's data-driven environment, which includes key aspects of data management and IT organizations. She manages the task of creating great content in the areas of software testing, DevOps, Robotic process automation. Connects with her on Linkedin and Twitter.
Upcoming Ansible Training Online classes
Batch starts on 25th Nov 2024 |
|
||
Batch starts on 29th Nov 2024 |
|
||
Batch starts on 3rd Dec 2024 |
|