AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,100 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example" published by Apress, and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible with_items vs loop: Migration Guide & Key Differences (2026)

By Luca Berton · Published 2024-01-01 · Category: installation

Complete guide to Ansible with_items vs loop. Understand the differences, migrate from with_* to loop, use loop_control, and handle complex iteration patterns with practical examples.

Ansible has two ways to iterate over data: the modern loop keyword (introduced in Ansible 2.5) and the legacy with_ keywords (with_items, with_dict, with_fileglob, etc.). This guide explains the differences, when to use each, and how to migrate.

Quick Comparison

Both produce identical results. The difference is in how they handle complex data.

Key Differences

| Feature | with_items | loop | |---------|-------------|--------| | Introduced | Ansible 1.x | Ansible 2.5 | | Auto-flattening | ✅ Yes (1 level) | ❌ No | | Syntax | with_items: list | loop: list | | Complex iteration | with_dict, with_nested, etc. | loop + filters | | Deprecation | Soft-deprecated (still works) | Recommended | | Performance | Same | Same |

with_items Auto-Flattening

The biggest behavioral difference — with_items automatically flattens one level of nested lists:

Migration: with_ to loop

with_items → loop

with_list → loop (identical)

with_dict → loop + dict2items

with_nested → loop + product

with_subelements → loop + subelements

with_sequence → loop + range

with_fileglob → loop + fileglob lookup

with_together → loop + zip

loop_control

The loop keyword works with loop_control for advanced iteration control:

Extended Loop Variables

With extended: true:

| Variable | Description | |----------|-------------| | ansible_loop.index | Current iteration (1-based) | | ansible_loop.index0 | Current iteration (0-based) | | ansible_loop.first | true on first iteration | | ansible_loop.last | true on last iteration | | ansible_loop.length | Total number of items | | ansible_loop.revindex | Iterations remaining (1-based) | | ansible_loop.previtem | Previous item | | ansible_loop.nextitem | Next item |

When to Use with_items vs loop

Use loop (recommended): • All new playbooks • Simple list iteration • When you need loop_control • When you want explicit behavior (no auto-flattening)

Use with_ (acceptable): • Legacy playbooks that work correctly • with_fileglob (simpler than lookup('fileglob', ..., wantlist=True)) • When the filter-based equivalent is significantly more complex • Maintaining consistency in an existing codebase

Is with_items Deprecated?

with_items and other with_ keywords are not officially deprecated as of Ansible 2.17/ansible-core 2.17. They are considered legacy and the documentation recommends loop, but they still work and will continue to work for the foreseeable future.

The ansible-lint tool flags with_ usage as a warning (rule no-jinja-when) but not as an error.

FAQ

What is the difference between with_items and loop in Ansible?

The main difference is auto-flattening: with_items automatically flattens one level of nested lists, while loop passes data as-is. For simple lists, they behave identically. loop is the modern recommended syntax and supports loop_control for advanced features.

Is with_items deprecated in Ansible?

No, with_items is not officially deprecated and still works in all current Ansible versions. However, it's considered legacy syntax. The Ansible documentation recommends using loop for new playbooks, and ansible-lint may flag with_ usage as a style warning.

How do I convert with_items to loop?

For simple lists, replace with_items directly with loop. If your data has nested lists and you relied on auto-flattening, add | flatten: loop: "{{ my_list | flatten }}". For with_dict, use loop: "{{ my_dict | dict2items }}".

Can I use loop_control with with_items?

No, loop_control only works with the loop keyword. This is one of the main reasons to migrate from with_items to loop — you gain access to label, index_var, pause, extended, and loop_var.

Which is faster, with_items or loop?

Performance is identical. Both iterate in the same way internally. The choice should be based on clarity and features, not performance.

Conclusion

For all new Ansible playbooks, use loop: • loop — Modern, explicit, supports loop_control • with_items — Legacy, auto-flattens, still works • Migration: Usually just rename with_items to loop; add | flatten if you relied on auto-flattening • with_dict → loop + dict2items; with_nested → loop + product

The filter-based approach with loop is more explicit and composable, making your playbooks easier to understand and maintain.

Related ArticlesAnsible loop_control: label, index_var, pause & loop_var GuideAnsible Flatten: Nested Lists in PlaybooksAnsible map Filter: Extract Attributes from ListsAnsible dict2items: Convert Dictionaries to Lists

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home