Ansible Loops and Conditionals: Solving Dynamic Variable Registration Challenges with with_items

Dec 07, 2025 · Programming · 6 views · 7.8

Keywords: Ansible | with_items | conditionals

Abstract: This article delves into the challenges of dynamic variable registration when using Ansible's with_items loops combined with when conditionals in automation configurations. Through a practical case study—formatting physical drives on multiple servers while excluding the system disk and ensuring no data loss—it identifies common error patterns in variable handling during iterations. The core solution leverages the results list structure from loop-registered variables, avoiding dynamic variable name concatenation and incorporating is not skipped conditions to filter excluded items. It explains the device_stat.results data structure, item.item access methods, and proper conditional logic combination, providing clear technical guidance for similar automation tasks.

In Ansible automation configuration management, combining loops with conditionals is a common requirement, but improper handling can lead to difficult-to-debug errors. This article explores how to correctly use with_items and when conditionals to avoid pitfalls in dynamic variable registration through a specific case study.

Problem Scenario Analysis

Assume we have multiple servers, each with four physical drives: /dev/sda, sdb, sdc, and sdd. The sda drive has the operating system installed, and we need to format the other drives, provided they contain no existing data. The initial implementation attempted the following steps:

  1. Retrieve all physical disk lists and store them in the disk_var variable.
  2. Check if each disk (excluding sda) is partitioned by using the stat module to detect the existence of the /dev/{{item}}1 path.
  3. If a disk is not partitioned, use the parted command to create a GPT partition table.

The key issue arises in variable passing between steps two and three. The initial code tried to register separate variable names for each loop item, such as base_secondary_partition_{{item}}, and then reference these dynamic variables in conditionals. However, Ansible's Jinja2 template engine does not support direct variable value access via string concatenation, leading to conditional evaluation failures with errors like: error while evaluating conditional: base_secondary_partition_sdd.stat.exists == false.

Solution: Leveraging Loop Registration Result Structure

When Ansible processes loop tasks, it collects all iteration results into a registered variable containing a results list. Each list element corresponds to one loop iteration, including the original item (accessible via the item attribute), task execution status (e.g., skipped, changed), and module return data (e.g., stat.exists).

The corrected code example is as follows:

- name: Check if the disk is partitioned and also ignore sda
  stat: path=/dev/{{item}}1
  with_items: "{{ disk_var }}"
  when: item != 'sda'
  register: device_stat

- name: Create GPT partition table
  command: /sbin/parted -s /dev/{{ item.item }} mklabel gpt
  with_items: "{{ device_stat.results }}"
  when:
    - item is not skipped
    - item.stat.exists == false

In the first task, the device_stat registered variable includes a results list, with each element corresponding to an item from disk_var (including sda, which is skipped by when: item != 'sda'). In the second task, we loop over device_stat.results and access the original disk identifier (e.g., sdb) via item.item. The conditional check has two parts: item is not skipped ensures excluded items (i.e., sda) are not processed, and item.stat.exists == false verifies that the disk is not partitioned.

Technical Details and Best Practices

This approach avoids the complexity of dynamic variable names by directly utilizing Ansible's built-in data structures. Key points to note include:

For more complex scenarios, consider using loop (Ansible 2.5+) as an alternative to with_items, though the core principles remain similar. It is always advisable to use the debug module during development to output registered variable structures, for example:

- debug:
    var: device_stat

This helps understand data formats and prevent common erroneous assumptions.

Conclusion

Through this case study, we have learned how to properly handle the interaction between loops and conditionals in Ansible. Key takeaways include avoiding dynamic variable name concatenation, leveraging the results list structure, and appropriately using is not skipped for filtering. These techniques are not only applicable to disk formatting tasks but also widely useful in other automation scenarios requiring iterative checks, improving Playbook reliability and readability.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.