Working with Lists in Ansible

Working with Lists in Ansible
In: Ansible NetDevOps

Hey everyone! In this blog post, let's dive into the world of Ansible and explore how to effectively work with lists. Lists are an essential part of any automation script, and Ansible is no exception. We'll go over some of the most common use cases, such as creating a list, adding and removing items, merging two lists, and even sorting and deduplicating lists, and more. Whether you're just starting out with Ansible or looking to sharpen your skills, this post is for you. Let's get started!

Creating a List in Ansible

When working with Ansible, you often need to manage groups of items, which is where lists come in handy. A list in Ansible is similar to lists in other programming languages. It's a collection of items, ordered, and changeable, and it allows duplicate members. Here's an example of how you can create a list in an Ansible playbook:

---
- name: Example of creating a list
  hosts: localhost
  gather_facts: False
  
  vars:
    my_list: ["item1", "item2", "item3"]

  tasks:
    - name: Print the list
      debug:
        msg: "{{ my_list }}"

In the provided Ansible playbook, we start by setting up the basics for any playbook, defining the name of the task and specifying the target hosts, which in this case is localhost. This means the playbook will run on the local machine. The gather_facts: False line tells Ansible not to gather system facts about the host, which can save time and resources if these facts are not needed for the playbook's tasks.

The vars section is where we define our variables. Here, we have created a variable named my_list and assigned it a list containing three string elements "item1", "item2", and "item3". This demonstrates how to initialize a list in Ansible.

Following the variable declaration, we have the tasks section. This is where the actions of the playbook are defined. In this example, there's only one task, which uses the debug module. The debug module is a useful tool in Ansible for printing messages or variables' values for debugging purposes. Here, it's used to print the contents of my_list to the console. When this playbook is run, it will output the elements of my_list, showing how lists are created and accessed in Ansible.

Adding an Item to a List in Ansible

To add an item to an existing list in Ansible, you can use the set_fact module. This module is used to create or modify variables during the execution of a playbook. Let's look at an example where we add an item to the my_list we created earlier.

---
- name: Example of adding an item to a list
  hosts: localhost
  gather_facts: False

  vars:
    my_list: ["item1", "item2", "item3"]
    
  tasks:
    - name: Add an item to the list
      set_fact:
        my_list: "{{ my_list + ['item4'] }}"
    - name: Print the updated list
      debug:
        msg: "{{ my_list }}"
  • We start with the initial list my_list containing "item1", "item2", and "item3".
  • The task Add an item to the list uses set_fact to modify my_list. We append 'item4' to the existing list by concatenating it. This is done using the Jinja2 templating syntax {{ my_list + ['item4'] }}.
  • Finally, we print the updated list using the debug module. It will now display item1, item2, item3, and the newly added item4.

Removing an Item from a List in Ansible

To remove an item from a list in Ansible, you typically use a combination of the set_fact module and a Jinja2 filter. In this example, we'll remove an item from the my_list we've been working with.

---
- name: Example of removing an item from a list
  hosts: localhost
  gather_facts: False

  vars:
    my_list: ["item1", "item2", "item3", "item4"]
    
  tasks:
    - name: Remove an item from the list
      set_fact:
        my_list: "{{ my_list | reject('equalto', 'item2') }}"
    - name: Print the updated list
      debug:
        msg: "{{ my_list }}"
  • We start with my_list which includes "item1", "item2", "item3", and "item4".
  • The task titled Remove an item from the list uses set_fact to redefine my_list.
  • The reject filter is applied to filter out the item 'item2'. The equalto test is used within the reject filter to specify the item to be removed.
  • After the removal, the debug module is used again to print the modified list. The output will show my_list without "item2".

Removing an Item by Index from a List in Ansible

As far as I know, Ansible does not have a direct method to remove an item by index like some programming languages do. However, you can do list slicing operation to remove an item from the list.

---
- name: Example of removing an item by index from a list
  hosts: localhost
  gather_facts: False

  vars:
    my_list: ["item1", "item2", "item3", "item4"]
    
  tasks:
    - name: Remove an item by index from the list
      set_fact:
        my_list: "{{ my_list[0:1] + my_list[2:] }}"
    - name: Print the updated list
      debug:
        msg: "{{ my_list }}"
  • The my_list initially contains "item1", "item2", "item3", and "item4".
  • The task to remove an item by index uses the set_fact module. The expression my_list[0:1] + my_list[2:] is a list slicing operation. It slices the list to exclude the item at index 1 (which is "item2" since lists are zero-indexed). This operation concatenates the slices before and after the item we want to remove.
  • The debug module then prints the updated list. In this case, the list will be displayed without "item2".

This method is useful when you know the specific position of the item you want to remove. It's a more direct approach compared to filtering by value and is especially handy when dealing with lists where the same value may appear multiple times, but you only want to remove a specific occurrence.

Removing Items Containing a Specific Substring from a List in Ansible

To remove items from a list in Ansible that contain a specific substring, you can use a combination of the reject filter and the search test in Jinja2. This method is effective for filtering out items based on partial-string matches. Here's an example where we remove items containing the substring '2' from my_list.

---
- name: Example of removing items containing a substring
  hosts: localhost
  gather_facts: False

  vars:
    my_list: ["item1", "item2", "item3", "item4", "item12"]
    
  tasks:
    - name: Remove items containing '2'
      set_fact:
        my_list: "{{ my_list | reject('search', '2') }}"
    - name: Print the updated list
      debug:
        msg: "{{ my_list }}"
  • my_list is initialized with several items, some of which contain the substring '2'.
  • The task titled Remove items containing '2' uses the set_fact module to redefine my_list. We apply the reject filter with the search test to filter out any items that contain the substring '2'.
  • The debug task then prints the updated list. The output will show my_list without the items that contained '2', which in this case would be "item2" and "item12".

Merging Two Lists in Ansible

Merging two lists in Ansible is a straightforward process. You can simply concatenate them using the + operator in a task with the set_fact module. Let's look at an example where we merge two lists, list1 and list2, into a new list merged_list

---
- name: Example of merging two lists
  hosts: localhost
  gather_facts: False

  vars:
    list1: ["item1", "item2", "item3"]
    list2: ["item4", "item5", "item6"]
    
  tasks:
    - name: Merge two lists
      set_fact:
        merged_list: "{{ list1 + list2 }}"
    - name: Print the merged list
      debug:
        msg: "{{ merged_list }}"
  • We define two lists list1 and list2 in the vars section, each containing different items.
  • The task named Merge two lists uses the set_fact module to create a new variable merged_list. This variable is assigned the concatenated result of list1 and list2, effectively merging them into one list.
  • The final task uses the debug module to print the new merged_list, which will display all the items from list1 followed by all the items from list2.

Finding Different Items Between Two Lists in Ansible

To find items that are different between two lists in Ansible, you can use a combination of Jinja2 filters: difference and unique. The difference filter compares two lists and returns the items that are unique to each list. The unique filter is often used to ensure that the resulting list contains no duplicate elements. Here's how you can use these filters to find the difference between two lists.

---
- name: Example of finding different items between two lists
  hosts: localhost
  gather_facts: False

  vars:
    list1: ["item1", "item2", "item3", "item4"]
    list2: ["item3", "item4", "item5", "item6"]
    
  tasks:
    - name: Find items unique to each list
      set_fact:
        unique_to_list1: "{{ list1 | difference(list2) | unique }}"
        unique_to_list2: "{{ list2 | difference(list1) | unique }}"
    - name: Print unique items
      debug:
        msg: "Items unique to list1: {{ unique_to_list1 }}, Items unique to list2: {{ unique_to_list2 }}"
  • We start by defining two lists, list1 and list2, each containing a mix of overlapping and unique items.
  • The task titled Find items unique to each list uses the set_fact module to create two new variables: unique_to_list1 and unique_to_list2.
    • unique_to_list1 is assigned the result of list1 | difference(list2) | unique, which computes the items that are in list1 but not in list2 and ensures all items are unique.
    • unique_to_list2 is similarly computed for items unique to list2.
  • The final task prints these unique items using the debug module. This output will help you see which items are exclusive to each list.

Flattening Nested Lists in Ansible

Flattening nested lists is a common requirement when dealing with complex data structures in Ansible. The flatten filter in Jinja2 is used to convert a list of lists into a single-level list by 'flattening' the structure. Here's an example of how you can use flatten to simplify a nested list.

---
- name: Example of flattening nested lists
  hosts: localhost
  gather_facts: False

  vars:
    nested_list: [["item1", "item2"], ["item3", "item4"], ["item5"]]
    
  tasks:
    - name: Flatten the nested list
      set_fact:
        flat_list: "{{ nested_list | flatten }}"
    - name: Print the flattened list
      debug:
        msg: "{{ flat_list }}"
  • We define a variable nested_list which contains several lists nested within it.
  • The task Flatten the nested list uses the set_fact module in conjunction with the flatten filter to transform nested_list into a single-level list, stored in a new variable flat_list.
  • The final task prints flat_list using the debug module. The output will show a single list with all the items from the nested lists combined into one sequence.

This method is especially useful in scenarios where you're aggregating data from multiple sources or handling complex data structures and need to simplify them for further processing or analysis.

Sorting Lists Alphabetically and Numerically in Ansible

Sorting lists is a fundamental operation in data manipulation. In Ansible, you can sort lists either alphabetically or numerically using the sort filter. Let's see two examples, one for sorting a list of strings alphabetically and another for sorting a list of numbers.

---
- name: Example of sorting a list alphabetically
  hosts: localhost
  gather_facts: False

  vars:
    string_list: ["banana", "apple", "cherry"]
    
  tasks:
    - name: Sort the list alphabetically
      set_fact:
        sorted_list: "{{ string_list | sort }}"
    - name: Print the sorted list
      debug:
        msg: "{{ sorted_list }}"
---
- name: Example of sorting a list numerically
  hosts: localhost
  gather_facts: False

  vars:
    number_list: [5, 1, 3]
    
  tasks:
    - name: Sort the list numerically
      set_fact:
        sorted_list: "{{ number_list | sort }}"
    - name: Print the sorted list
      debug:
        msg: "{{ sorted_list }}"

Deduplicating Lists in Ansible

List deduplication is a process of removing duplicate entries from a list in Ansible. This can be especially useful when dealing with dynamic data where duplicates may arise. Ansible's unique filter comes in handy for this task. Here's an example demonstrating how to deduplicate a list.

---
- name: Example of list deduplication
  hosts: localhost
  gather_facts: False

  vars:
    duplicate_list: ["apple", "banana", "apple", "orange", "banana", "apple"]
    
  tasks:
    - name: Deduplicate the list
      set_fact:
        unique_list: "{{ duplicate_list | unique }}"
    - name: Print the deduplicated list
      debug:
        msg: "{{ unique_list }}"
  • The variable duplicate_list is initialized with a list that contains several duplicate items.
  • The task titled Deduplicate the list utilizes the set_fact module along with the unique filter to remove any duplicate entries from duplicate_list. The result is stored in a new variable, unique_list.
  • The final task uses the debug module to print unique_list. The output will display each item from the original list, but without any duplicates. For instance, "apple", "banana", and "orange" will each appear only once in the unique_list.

Closing Up

And that wraps up our exploration of list manipulation in Ansible! We've covered a range of techniques, from creating and modifying lists to more advanced operations like merging, deduplicating, and sorting. These skills are essential for anyone working with Ansible, as they allow for more efficient and effective playbook development. Stay tuned for more Ansible insights in future posts. Happy automating!

Table of Contents
Written by
Suresh Vina
Tech enthusiast sharing Networking, Cloud & Automation insights. Join me in a welcoming space to learn & grow with simplicity and practicality.
Comments
More from Packetswitch
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Packetswitch.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.