Advanced Ansible and Jinja2

Ansible’s power lies in its ability to handle complex data structures with minimal code. By leveraging Jinja2 filters, you can elegantly transform data to meet automation requirements. This article explores a practical example of converting a simple list into a structured list of dictionaries, highlighting the flexibility and efficiency of Jinja2 in Ansible.

Scenario: Transforming vmlist to vmlist2

Imagine you have a list of virtual machine names (vmlist), and you need to convert it into a list of dictionaries (vmlist2), where each dictionary includes the key name with the corresponding value from vmlist.

Input Data

vmlist:
  - "a"
  - "b"

Desired Output

vmlist2:
  - name: "a"
  - name: "b"

The Jinja2 Solution

Here’s a compact and efficient way to achieve this transformation using Jinja2 filters:

vmlist2: {{ vmlist | map('regex_replace', '(.*)', '{"name": "\\1"}') | map('from_json') | list }}

Step-by-Step Breakdown

  1. map('regex_replace', '(.*)', '{"name": "\\1"}'):

    • Applies a regex to each element in vmlist, wrapping it into a JSON string.
    • Example: "a" becomes {"name": "a"}.
  2. map('from_json'):

    • Converts the JSON string into a Python dictionary.
    • Example: {"name": "a"} is now a usable dictionary in Ansible.
  3. list:

    • Ensures the final output is a proper list of dictionaries.

Usage in an Ansible Playbook

Here’s how to use this transformation in an actual playbook:

- name: Transform vmlist to vmlist2
  hosts: localhost
  vars:
    vmlist:
      - "a"
      - "b"
  tasks:
    - name: Transform vmlist to vmlist2
      set_fact:
        vmlist2: "{{ vmlist | map('regex_replace', '(.*)', '{"name": "\\1"}') | map('from_json') | list }}"

    - name: Display transformed vmlist2
      debug:
        var: vmlist2

Output

When you run the playbook, the output will be:

vmlist2:
  - name: "a"
  - name: "b"

Alternative Approaches

While the above method uses regex for transformation, alternative solutions avoid regex for simplicity and better readability. For example:

vmlist2: [
{% for vm in vmlist %}
  {"name": "{{ vm }}"}{% if not loop.last %},{% endif %}
{% endfor %}
]

This approach uses a loop to achieve the same result without relying on regex or JSON conversion.

Conclusion

Ansible’s integration with Jinja2 provides a robust toolkit for handling data transformations, enabling complex automation workflows with concise code. By understanding filters like map, regex_replace, and from_json, you can unlock powerful solutions tailored to your automation needs.

For more insights into advanced Ansible techniques, check out my book and video tutorials.

Join 50+ hours of courses in our exclusive community

Academy

Learn the Ansible automation technology with real-life examples in my Udemy 300+ Lessons Video Course.

BUY the Complete Udemy 300+ Lessons Video Course

My book Ansible By Examples: 200+ Automation Examples For Linux and Windows System Administrator and DevOps

BUY the Complete PDF BOOK to easily Copy and Paste the 250+ Ansible code

Want to keep this project going? Please donate.

Patreon Buy me a Pizza