Ansible Loops

Last updated: June 30, 2025

My Journey with Ansible Loops

When I first started working with Ansible, I quickly found myself repeating tasks in my playbooks. I was writing the same task multiple times with slight variations—creating users, installing packages, configuring services with different parameters. This approach not only made my playbooks unnecessarily lengthy but also difficult to maintain.

That's when I discovered the power of loops in Ansible. Learning to use loops transformed the way I write playbooks. Suddenly, I could define a single task that would execute multiple times with different inputs. My playbooks became shorter, more maintainable, and much more powerful.

In this blog post, I'll share my experience with Ansible loops, demonstrating how they can simplify automation across both Linux and Windows environments. Whether you're managing a handful of servers or a complex multi-platform infrastructure, mastering loops will take your Ansible automation to the next level.

Understanding Loops in Ansible

Loops in Ansible allow you to perform the same task multiple times with different values. This concept is similar to programming language loops, especially Python's for loop. If you're familiar with other programming languages, you'll find Ansible loops quite intuitive.

Historically, Ansible provided various ways to implement loops:

  1. The legacy with_* keywords (e.g., with_items, with_file)

  2. The modern loop keyword (introduced in Ansible 2.5)

While with_* keywords are still supported for backward compatibility, the Ansible documentation recommends using the loop keyword for most use cases as it provides a more consistent and predictable interface.

Basic Loop Usage

Let's start with a simple example. Imagine you need to create multiple users on your Linux servers:

---
- name: Create multiple users
  hosts: linux_servers
  tasks:
    - name: Add several users
      ansible.builtin.user:
        name: "{{ item }}"
        state: present
        groups: "wheel"
      loop:
        - devuser
        - testuser
        - adminuser

In this example, the user module will run three times, once for each value in the loop. The {{ item }} variable holds the current value in each iteration.

For Windows servers, a similar approach can be used:

Working with Lists of Dictionaries

Often, you'll need to provide multiple parameters for each iteration. For this, you can use a list of dictionaries:

Linux Example:

Windows Example:

Iterating Over Dictionaries

Working with dictionaries in loops requires a different approach. Ansible provides the dict2items filter for this purpose:

This task iterates through the dictionary, allowing you to access both the keys and values.

Nested Loops

For more complex scenarios, you might need nested loops. While Ansible doesn't have a direct nested loop construct, you can achieve the same result using Jinja2's product filter:

This will create all combinations of users and databases, resulting in nine iterations of the task.

Loop Control

Ansible provides the loop_control directive to manage loop behavior:

Limiting Output

When dealing with large loops, the output can become unwieldy. Use the label directive to make the output more readable:

Instead of showing the entire item dictionary in the output, Ansible will only display the package name.

Tracking Loop Progress

You can track the current position in a loop using the index_var directive:

Extended Loop Information

For advanced loop control, use the extended option:

Looping with Conditionals

Combining loops with conditionals gives you even more flexibility:

Linux Example:

Windows Example:

Registering Variables with Loop

You can capture the results of a loop using the register keyword:

When registering the result of a loop, Ansible creates a list in the .results attribute of the registered variable. Each element in this list corresponds to an iteration of the loop.

Loop Until a Condition is Met

Sometimes you need to repeat a task until a specific condition is met. The until keyword combined with retries and delay allows for this:

This task will retry up to 10 times with a 5-second delay between attempts until it gets a 200 status code from the health endpoint.

Sequence Diagram: How Loops Work in Ansible

Here's a sequence diagram that illustrates how loops are processed in Ansible:

spinner

This diagram shows how Ansible processes each item in a loop, replacing the item variable with the current value before executing the task on the target host.

Performance Considerations

While loops are powerful, they can impact performance since each iteration requires a separate connection to the target host. Here are some tips for optimizing loop performance:

  1. Use module parameters when possible: Many modules accept lists directly:

  2. Use loop_control.pause for rate limiting: When hitting external APIs or services that might have rate limits:

Real-World Examples

Let's look at some real-world examples that combine multiple concepts we've discussed.

Linux Server Configuration

Windows Environment Setup

Common Pitfalls and Solutions

Mistake: Using loop with strings

Solution: Convert the string to a list:

Mistake: Nested structure flattening issues

Solution: Use the flatten filter with appropriate level:

Mistake: Not accessing loop results correctly

Solution: Access through the results list:

Conclusion

Loops are a fundamental feature in Ansible that can significantly improve the efficiency and maintainability of your playbooks. They allow you to perform repetitive tasks with different inputs while keeping your code DRY (Don't Repeat Yourself). Whether you're managing Linux servers, Windows environments, or a hybrid infrastructure, mastering loops will help you create more elegant and powerful automation.

As I've discovered in my automation journey, the time invested in learning how to properly use loops in Ansible pays off immensely as your infrastructure grows and your playbooks become more complex. Start with simple loops and gradually incorporate the more advanced features as you gain confidence.

Last updated