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
``yaml
vmlist:
- "a"
- "b"
`
Desired Output
`yaml
vmlist2:
- name: "a"
- name: "b"
`
The Jinja2 Solution
Here’s a compact and efficient way to achieve this transformation using Jinja2 filters:
`jinja
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:
`yaml
- 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:
`yaml
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:
`jinja
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.