Loops deserve a special mention in this chapter. So far, we have focused on controlling the flow of a playbook in a top-to-bottom fashion—we have changed the various conditions that might be evaluated as the playbook runs, and we have also focused on creating concise efficient code. What happens, however, if you have a single task, but need to run it against a list of data; for example, creating several user accounts, or directories, or indeed something more complex.
Looping changed in Ansible 2.5—prior to this, loops were generally created with keywords such as with_items. Although some backward compatibility remains, it is advisable to move to the newer loop keyword instead.
Let's take a simple example—we need to create two directories. Create loop.yaml as follows:
---
- name: looping demo
hosts: localhost
gather_facts: false
tasks:
- name: create a directory
file:
path: /srv/whiskey/alpha
state: directory
- name: create another directory
file:
path: /srv/whiskey/beta
state: directory
When we run this, as expected, our two directories get created:
However, you can see this code is repetitive and inefficient. Instead, we could change it to something like this:
---
- name: looping demo
hosts: localhost
gather_facts: false
tasks:
- name: create a directory
file:
path: "{{ item }}"
state: directory
loop:
- /srv/whiskey/alpha
- /srv/whiskey/beta
Note the use of the special variable item, which is now used to define the path from the loop items at the bottom of the task. Now, when we run this code, the output looks somewhat different:
The two directories were still created exactly as before, but this time within a single task. This makes our playbooks much more concise and efficient. Ansible offers many more powerful looping options, including nested loops and the ability to create loops that will carry on until a given criterion is met (often referred to as do until loops), as opposed to a specific limited set of data. Full details of these are available in the Ansible documentation here: https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html.