“Ansible is an open-source tool from Red Hat Inc., which is used for automating many of the IT infrastructure tasks. It can be used for a wide range of tasks such as installing software packages, adding compute nodes, resource provisioning, and many others. It has a number of modules that can be used to manage multiple configuration-related tasks.
Ansible is agentless and is installed on a controlling host called a controller. The controller work is to manage remote machines via SSH and other supported communication mechanisms.
Loops are handy for performing multiple tasks in one shot, such as creating multiple users, installing multiple packages, or repeatedly executing a task until a condition is true or false.
Ansible uses YAML(YAML Ain’t Markup Language), a data serialization language, for its playbooks. An Ansible code can be minimized by using Loops, i.e., iterating over sequences or mappings.”
What Will We Cover?
In this guide, we will talk about Loops in Ansible and see some specific examples of using them inside playbooks.
Prerequisites
1. Basics of Ansible: Working and how to run playbooks.
2. Lab for performing this guide: You can set it using Vagrant and VirtualBox.
Loops in Ansible
Ansible provides three keywords for performing a loop operation: loop, with_<lookup>, and until. Loops are usually used to create multiple users, modifying the ownership for files and directories and iterating over an instruction until a condition is satisfied.
Standard or Simple Loops
Standard loops can be used for iterating over a simple list of strings that can be defined directly inside a task, as shown below. Let us take a simple example of this. Create a playbook:
$ nano my-playbook - name: Add multiple users hosts: managed1 become: yes tasks: - name: Add three users using Loops user: name: "{{ item }}" state: present loop: - myuser1 - myuser2
In the above playbook, Ansible creates multiple users in a single task using Loops. Also, it uses the “user” module to create the above users.
For every iteration of the loop, the values of the list are substituted in the item variable.
Explaining the Playbook
- In the “user” module, we have not given any name directly; instead, a variable {{ item }} is used with the “name” parameter.
- Under the “loop” keyword, the user names to be used are listed. These usernames replace the {{ item }} when the playbook is actually executed.
- While executing the task, it is listed only once, but three modifications are listed just below it. We will see it soon.
Loops Over a List of Hashes
Loops can also be used to iterate over hashes. For instance, if the users need to be assigned to distinct additional groups, we need to do it as:
- username: my_user1 groups: production - username: my_user2 groups: development - username: my_user3 groups: staging
Here, the groups are already present on the remote machines. We are just adding them to the users using Loops.
An optional parameter called “groups” is used by the “user” module for listing additional users. For a list of hashes, we can reference subkeys in a loop. For this purpose, we use the {{ item }} keyword. As an illustration, consider the below snippet of a playbook:
- name: Add multiple users hosts: managed1 become: yes tasks: - name: Add three users using Loops ansible.builtin.user: name: "{{ item.username }}" state: present groups: "{{ item.groups }}" loop: - { username: 'my_user1', groups: 'production' } - { username: 'my_user2', groups: 'development' } - { username: 'my_user3', groups: 'staging' }
Ansible Loops With Conditionals
Conditionals can be used with loops to iterate over a sequence until a condition is true. For example, the “when” statement can be used for this purpose. In this case, each condition is separately processed by the Ansible. Using this technique, a task can be executed for some items and skipped for others; for example, consider the case below:
tasks: - name: Print numbers smaller than 46 ansible.builtin.command: echo {{ item }} loop: [ 1, 5, 44, 56, 48, 9, 4 ] when: item < 46
The task should print all the items, here numbers smaller than 46, when it is run and print the result on the terminal. The complete my-playbook.yml, in this case, will be:
--- - hosts: all gather_facts: yes become: true tasks: - name: Print numbers smaller than 46 ansible.builtin.command: echo {{ item }} loop: [ 1, 5, 44, 56, 48, 9, 4 ] when: item < 46
Now run the execute the playbook using the command below:
$ ansible-playbook my_playbook.yml -i /path/to/inventory/file
Here echo command will run on those values of the items that are smaller than 46; this can be noted from the output on the terminal.
Conclusion
In this guide, we have learned about Ansible Loops and seen various use cases. To explore more about “how to use loops with dictionaries, indexes, etc.”, please refer to the Ansible official documentation.
References: