Ansible is a powerful tool for automating tasks, but when working with dynamically generated data, such as Ansible facts, it can sometimes be tricky to produce clean, well-formatted output. This article demonstrates how to use Jinja2 templating within an Ansible playbook to transform facts into clean YAML, ensuring proper indentation and formatting.
In this example, we'll look at a different scenario: transforming networking data (like interfaces, IP addresses, and MAC addresses) into a nicely formatted YAML structure. We'll cover how to loop through facts, control whitespace in Jinja2, and generate a neat YAML file.
Scenario: Formatting Network Interfaces
Imagine you are managing a fleet of servers and you need to produce a YAML report that lists each network interface's details, including its name, IP address, MAC address, and the status of the connection.
Here's an Ansible task that gathers network facts and formats them into clean YAML output.
Ansible Playbook Example
``yaml
---
- name: Generate network interface report
hosts: localhost
gather_facts: yes
tasks:
- name: Transform network interfaces into YAML
set_fact:
network_yaml: |
interfaces:
{% for iface_name, iface_data in ansible_facts['ansible_interfaces'].items() %}
- name: {{ iface_name }}
mac_address: {{ iface_data.macaddress | default('unknown') }}
ip_address: {{ iface_data.ipv4.address | default('N/A') }}
status: {{ iface_data.active | ternary('up', 'down') }}
{% endfor %}
- name: Save the formatted network interfaces to a file
copy:
content: "{{ network_yaml }}"
dest: /tmp/network_interfaces.yaml
`
Breaking Down the Example
1. Gathering Facts:
We start by setting gather_facts: yes, which collects information about the target machine. In this case, we focus on the ansible_interfaces fact, which contains data about each network interface on the machine.
2. Looping Through Interfaces:
Using Jinja2 templating, we iterate over the ansible_interfaces dictionary. For each interface, we access its name, MAC address, IP address, and status (whether it's active or inactive).
3. Whitespace Control:
Proper indentation is crucial in YAML, so we ensure that the loop outputs are correctly aligned by adjusting the placement of the Jinja2 tags within the template.
4. Using Filters:
- default: If a MAC address or IP is not present, we use this filter to insert a default value ('unknown' or 'N/A').
- ternary: This filter is used to convert the active boolean value into human-readable statuses ('up' for true, 'down' for false).
5. Saving the Output:
The copy module saves the generated YAML content to /tmp/network_interfaces.yaml.
Sample Output
When this playbook is run on a machine, the output YAML file might look like this:
``yaml
interfaces:
- name: eth0