Ansible snippets - manipulating JSON data

Ansible snippets - manipulating JSON data

Recently while working with Ansible, I needed a clean way to extract JSON values and manipulate that data in a very Ansible-esque way. In this particular case, reading JSON files/variables and treating them as if they were Ansible variables, converting that list into a comma-seperated string. Turns out Ansible can handle that pretty easily, using Jinja filters.

scenario and demo

The following steps will use the example playbook json_example.yml.

Let’s say you need to extract JSON values from a file (or variable), for use somewhere else. The particular case I ran into was I needed specific values in a comma seperated list. First step, read in the JSON value:

    - name: Read JSON file (can also be a variable).
      shell: cat files/example.json
      register: json

This works if the JSON is a variable:

# replace future json.stdout variables with json_example
json_example: |
  {
      "example_simple": {
	  "name": "simple",
	  "foo": "value",
	  "item": "this"
      },
      "example_list": [
	  {
	      "name": "first",
	      "foo": "bar",
	      "item": "thud"
	  },
	  {
	      "name": "second",
	      "foo": "grunt",
	      "item": "baz"
	  }
      ]
  }

In this particular snippet, we’re looking to get the name value from the example_simple dictionary:

    - name: Get simple value.
      set_fact:
        simple_value: "{{ (json.stdout | from_json).example_simple.name }}"

The from_json filter allows Ansible to treat it much like a variable, extracting out the value of the name variable.

A slightly more complicated example is pulling out the values in the list of dictionaries, example_list, in this case, getting the foo value:

    - name: Get foo value.
      set_fact:
        foo_value: "{{ (json.stdout | from_json).example_list | map(attribute='foo') | list }}"

This will return an Ansible list. The next debug statement is also slightly more complex, as it prints out the list in a comma-seperated format:

    - name: Jinja list debug, printing out the list as comma seperated.
      debug:
        msg: "{% for each in foo_value %}{{ each }}{% if not loop.last %},{% endif %}{% endfor %}"

The above is useful when templating config files.

summary

Some quick and dirty Ansible JSON manipulation. We’re able to read a JSON file/variable and treat it as if it were an Ansible variable. From there, using Jinja filters, we can convert that list into a comma-seperated string, or any other needed format. It’s a very useful technique to import JSON values and treat them as Ansible variables.