Skip to main content

Implementing Loops

1. Using Simple Loops

Loop Type Description Example
loop Iterates over a list of items
- name: Print each item in a list
  debug:
    msg: "Item is {{ item }}"
  loop:
    - apple
    - banana
    - cherry
with_items Deprecated alternative to loop (still supported)
- name: Print each item in a list
  debug:
    msg: "Item is {{ item }}"
  with_items:
    - apple
    - banana
    - cherry

Example: Looping over a list of files

- name: Ensure all config files exist
  file:
    path: "/etc/{{ item }}"
    state: touch
  loop:
    - nginx.conf
    - apache.conf
    - mysql.conf

Example: Using loop with a variable

- name: Create directories
  file:
    path: "/opt/{{ item }}"
    state: directory
  loop: "{{ directories }}"

2. Looping with Lists

Property Description Example
loop Iterates over a list of items loop: ['item1', 'item2', 'item3']
with_items Alternative syntax for looping over lists (deprecated) with_items: ['item1', 'item2']
loop_var Variable name to reference current item in loop loop_var: item

Example: Looping over a list of packages

- name: Install packages
  apt:
    name: "{{ item }}"
    state: present
  loop:
    - git
    - curl
    - vim

Example: Using loop_var to access item index

- name: Create directories
  file:
    path: "/tmp/dir_{{ item }}"
    state: directory
  loop:
    - one
    - two
    - three
  loop_var: dir_name

3. Looping with Dictionaries

Property Description Example
loop Iterates over a dictionary, providing key and value
- name: Loop through dictionary
  debug:
    msg: "Key is {{ item.key }} and value is {{ item.value }}"
  loop: "{{ my_dict }}"
loop Accessing dictionary keys and values using item.key and item.value
- name: Loop through dictionary keys
  debug:
    msg: "Key is {{ item.key }}"
  loop: "{{ my_dict }}"

Example: Looping Through a Dictionary

- name: Loop through dictionary
  debug:
    msg: "Key is {{ item.key }} and value is {{ item.value }}"
  loop: "{{ my_dict }}"

Example: Looping Through Dictionary Keys

- name: Loop through dictionary keys
  debug:
    msg: "Key is {{ item.key }}"
  loop: "{{ my_dict }}"
Note: When looping over a dictionary, item.key and item.value are used to access the key and value respectively.

4. Using Loop Control

Control Option Description Example
loop_control Controls how the loop behaves, including labels and pause behavior
{% for item in items %}
  {% loop_control label="process_item" %}
  {{ item }}
{% endfor %}
loop_var Customizes the variable name used in the loop
{% for item in items %}
  {{ item }}
{% endfor %}
index_var Customizes the index variable name in loops
{% for item in items %}
  Item {{ item }} at index {{ index }}
{% endfor %}

Example: Loop Control with Label

- name: Process items with label
  debug:
    msg: "Processing item {{ item }}"
  loop: "{{ items }}"
  loop_control:
    label: "item_{{ item }}"

Example: Loop Control with Index

- name: Process items with index
  debug:
    msg: "Item {{ item }} at position {{ index }}"
  loop: "{{ items }}"
  loop_control:
    index_var: "index"

5. Setting Loop Variable Name

Property Description Default Value Example
loop_var Variable name to use for the current item in the loop item
- name: Loop with custom variable
  debug:
    msg: "Processing {{ my_var }}"
  loop: [1, 2, 3]
  loop_control:
    loop_var: my_var

Example: Using loop_var in a task

- name: Process items with custom loop variable
  debug:
    msg: "Current item is {{ custom_item }}"
  loop: ["apple", "banana", "cherry"]
  loop_control:
    loop_var: custom_item

6. Adding Loop Labels

Property Description Example
loop_control.label Assigns a custom label to each loop iteration for easier debugging and logging.
- name: Loop with custom label
  debug:
    msg: "Processing item {{ item }}"
  loop:
    - apple
    - banana
    - cherry
  loop_control:
    label: "Fruit: {{ item }}"

Example: Using loop_control.label

- name: Process files with labels
  copy:
    src: "{{ item }}"
    dest: "/tmp/{{ item }}"
  loop:
    - file1.txt
    - file2.txt
    - file3.txt
  loop_control:
    label: "Copying {{ item }}"

7. Using Loop Index

Property Description Usage
loop.index Current iteration count (1-based) {{ loop.index }}
loop.index0 Current iteration count (0-based) {{ loop.index0 }}
loop.revindex Remaining iterations (1-based) {{ loop.revindex }}
loop.revindex0 Remaining iterations (0-based) {{ loop.revindex0 }}
loop.first True if first iteration {{ loop.first }}
loop.last True if last iteration {{ loop.last }}
loop.length Total number of iterations {{ loop.length }}

Example: Using loop.index in a task

- name: Create files with index
  file:
    path: "/tmp/file_{{ loop.index }}.txt"
    state: touch
  loop:
    - one
    - two
    - three

Example: Using loop.revindex in a task

- name: Display reverse index
  debug:
    msg: "Processing item {{ item }} - {{ loop.revindex }} remaining"
  loop:
    - apple
    - banana
    - cherry

8. Pausing Between Iterations

Option Values Notes
loop_control pause Pauses execution between iterations
sleep seconds Number of seconds to pause between iterations

Example: Pausing Between Loop Iterations

- name: Pause between iterations
  debug:
    msg: "Processing item {{ item }}"
  loop: [1, 2, 3]
  loop_control:
    pause: 2
Note: The pause option is available in Ansible 2.10 and later.

9. Looping Until Condition

Option Values Description
until condition Condition to check after each iteration
retries 5 Maximum number of retries before failing
delay 1 Seconds to wait between retries

Example: Looping Until a File Exists

- name: Wait until file exists
  wait_for:
    path: /tmp/myfile.txt
    timeout: 30
  register: result
  until: result.stat.exists
  retries: 5
  delay: 2

Example: Looping Until a Service is Running

- name: Check service status
  command: systemctl is-active myservice
  register: service_status
  until: service_status.stdout == "active"
  retries: 10
  delay: 1

10. Using Legacy Loops

Loop Type Description Usage Notes
with_items Iterates over a list of items tasks:
- name: Process items
debug:
msg: "Processing {{ item }}"
with_items:
- item1
- item2
Legacy loop syntax; replaced by loop
with_dict Iterates over dictionary keys and values tasks:
- name: Process dict
debug:
msg: "Key: {{ item.key }}, Value: {{ item.value }}"
with_dict:
key1: value1
key2: value2
Legacy loop syntax; replaced by loop
with_sequence Generates a sequence of numbers tasks:
- name: Generate sequence
debug:
msg: "Number: {{ item }}"
with_sequence:
start: 1
end: 5
Legacy loop syntax; replaced by loop
with_lines Iterates over lines in a string variable tasks:
- name: Process lines
debug:
msg: "Line: {{ item }}"
with_lines:
- line1
- line2
Legacy loop syntax; replaced by loop
Note: The with_* loop syntax is deprecated in favor of the more flexible loop keyword introduced in Ansible 2.5.

11. Flattening Nested Lists

Property Description Example
flattened Flattens nested lists into a single list
- name: Flatten nested lists
  set_fact:
    flat_list: "{{ [[1, 2], [3, 4], [5, 6]] | flatten }}"
flatten Alias for flattened, used in loops and tasks
- name: Use flattened in loop
  debug:
    msg: "Item: {{ item }}"
  loop: "{{ nested_list | flatten }}"

Example: Flattening nested lists in a task

- name: Flatten nested lists
  set_fact:
    flattened_data: "{{ [[1, 2], [3, 4], [5, 6]] | flatten }}"
Note: The flatten filter works recursively and can handle deeply nested lists.

Example: Flattening with multiple levels

- name: Flatten deeply nested lists
  set_fact:
    deep_flat: "{{ [[[1, 2], [3]], [[4, 5], [6]]] | flatten }}"

12. Using Loop with Conditionals

Property Description Example
loop Iterates over a list or dictionary
- name: Process items with condition
  debug:
    msg: "Processing {{ item }}"
  loop: "{{ items }}"
  when: item is defined
when Conditional execution based on a fact or variable
- name: Install packages only if not installed
  apt:
    name: "{{ item }}"
    state: present
  loop: "{{ packages }}"
  when: "'{{ item }}' not in installed_packages"

Example: Loop with Conditional Filter

- name: Configure services only if enabled
  systemd:
    name: "{{ item.name }}"
    state: "{{ item.state }}"
  loop: "{{ services }}"
  when: item.enabled
Note: The when clause is evaluated for each loop iteration, allowing conditional logic per item.

Was this article helpful?