Mastering Ansible Loop in 5 Minutes

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.

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.

Scroll to Top