Introduction
Modern IT automation often requires handling complex JSON data, whether from APIs, configuration files, or dynamic inputs. Ansible, with its powerful filters like from_json and json_query, provides an elegant way to parse and transform JSON data into actionable formats. This guide walks you through parsing JSON data and transforming it into a structured list in an Ansible playbook.
The Scenario
You have a JSON string representing a nested structure, such as:
{
"results": [
{ "instance": { "guest": { "guestState": "running" } }, "item": "foo" },
{ "instance": { "guest": { "guestState": "running" } }, "item": "bar" },
{ "instance": { "guest": { "guestState": "running" } }, "item": "baz" },
{ "instance": { "guest": { "guestState": "running" } }, "item": "qux" },
{ "instance": { "guest": { "guestState": "running" } }, "item": "quux" }
]
}
The goal is to transform this JSON into a structured list:
formatted_list:
- { name: "foo", guestState: "running" }
- { name: "bar", guestState: "running" }
- { name: "baz", guestState: "running" }
- { name: "qux", guestState: "running" }
- { name: "quux", guestState: "running" }
The Playbook
Here’s how you can achieve this transformation:
Ansible Code
---
- hosts: localhost
gather_facts: false
tasks:
- name: Define Raw JSON String (Example - in real use, this comes from a variable)
set_fact:
raw_json_string: >
{
"results": [
{ "instance": { "guest": { "guestState": "running" } }, "item": "foo" },
{ "instance": { "guest": { "guestState": "running" } }, "item": "bar" },
{ "instance": { "guest": { "guestState": "running" } }, "item": "baz" },
{ "instance": { "guest": { "guestState": "running" } }, "item": "qux" },
{ "instance": { "guest": { "guestState": "running" } }, "item": "quux" }
]
}
- name: Parse JSON string to dictionary
set_fact:
json_data: "{{ raw_json_string | from_json }}"
- name: Transform JSON to formatted list
set_fact:
formatted_list: "{{ json_data.results | json_query('[].{name: item, guestState: instance.guest.guestState}') }}"
- name: Display formatted list
debug:
msg: "Formatted List: {{ formatted_list }}"
Explanation
Key Steps
-
Define Raw JSON String:
- Use the
set_factmodule to define a raw JSON string. - In real scenarios, this JSON could come from an API, a file, or another source.
- Use the
-
Parse JSON String:
- The
from_jsonfilter converts the JSON string into a Python dictionary, enabling further manipulation.
- The
-
Transform JSON Data:
- Use the
json_queryfilter to extract and restructure the JSON. - Query:
[].{name: item, guestState: instance.guest.guestState}.- Extracts
itemasname. - Extracts
instance.guest.guestStateasguestState.
- Extracts
- Use the
-
Display Results:
- The
debugmodule outputs the transformed list for validation.
- The
Output
After running the playbook, the debug task will display:
Formatted List:
- { name: "foo", guestState: "running" }
- { name: "bar", guestState: "running" }
- { name: "baz", guestState: "running" }
- { name: "qux", guestState: "running" }
- { name: "quux", guestState: "running" }
How to Use This Playbook
-
Save:
- Save the code as a YAML file (e.g.,
transform.yml).
- Save the code as a YAML file (e.g.,
-
Run:
- Execute the playbook using:
ansible-playbook transform.yml
- Execute the playbook using:
-
Verify Output:
- Ensure the transformed list is displayed correctly in the debug task.
Important Notes
-
From JSON to Dict: Use the
from_jsonfilter only if the raw JSON is a string. If your JSON data is already a dictionary, you can skip this step. -
Install JMESPath: The
json_queryfilter requires the JMESPath Python library. Install it with:pip install jmespath -
Dynamic JSON Sources: Replace the hardcoded
raw_json_stringwith actual data sources, such as API responses using theurimodule.
Conclusion
Ansible’s from_json and json_query filters are powerful tools for handling and transforming JSON data. By leveraging these features, you can streamline complex data manipulations, making your playbooks more dynamic and efficient.
Start incorporating these techniques in your automation workflows today!