Introduction
When working with Ansible playbooks, comparing two lists is a common task, especially for validating data consistency in automation workflows. However, users often encounter issues with filters like length, particularly in older Ansible versions or due to syntax ambiguities. This guide demonstrates how to effectively compare lists, ensuring they match in both size and content.
---
The Scenario: Comparing Two Lists
Consider the following two lists:
``yaml
list_one:
- { name: "foo" }
- { name: "bar" }
- { name: "baz" }
- { name: "qux" }
- { name: "quux" }
list_two:
- { name: "foo" }
- { name: "bar" }
- { name: "baz" }
- { name: "quux" }
`
The goal is to:
1. Verify that both lists are of equal length.
2. Check that all elements in list_one are present in list_two, and vice versa.
3. Fail gracefully if there are mismatches.
---
Playbook: Comparing Two Lists
Here’s the complete playbook to achieve this:
Example Playbook
`yaml
---
- name: Compare two lists
hosts: localhost
vars:
list_one:
- { name: "foo" }
- { name: "bar" }
- { name: "baz" }
- { name: "qux" }
- { name: "quux" }
list_two:
- { name: "foo" }
- { name: "bar" }
- { name: "baz" }
- { name: "quux" }
tasks:
- name: Verify if lengths of both lists are equal
debug:
msg: "The lists are of equal length."
when:
- "{{ list_one | length == list_two | length }}"
- name: Verify if all names in list_one are in list_two
debug:
msg: "All names in list_one are present in list_two."
when:
- "{{ list_one | map(attribute='name') | difference(list_two | map(attribute='name')) | length == 0 }}"
- name: Verify if all names in list_two are in list_one
debug:
msg: "All names in list_two are present in list_one."
when:
- "{{ list_two | map(attribute='name') | difference(list_one | map(attribute='name')) | length == 0 }}"
- name: Fail if lists are not of equal length or contain different elements
fail:
msg: "The lists do not match in length or elements."
when:
- "{{ list_one | length != list_two | length }}"
- "{{ list_one | map(attribute='name') | difference(list_two | map(attribute='name')) | length != 0 }}"
- "{{ list_two | map(attribute='name') | difference(list_one | map(attribute='name')) | length != 0 }}"
`
---
Key Features of the Playbook
Length Comparison
- Ensures both lists are of the same size using the length
filter.
Element Comparison
- Extracts name
attributes withmap(attribute='name').
- Uses the difference
filter to identify mismatched elements between the lists.
Fail Gracefully
- The fail
module provides clear error feedback when the lists differ in length or content.
---
Why It Works
1. Explicit Template Syntax:
- Wrapping conditions in {{ ... }}` ensures clear, unamb