Bootstrap FreeKB - Ansible - Getting Started parsing JSON
Ansible - Getting Started parsing JSON

Updated:   |  Ansible articles

Almost always, you will be working with JSON when obtaining data using an Ansible module and then using the register parameter to store the JSON in a variable. In this example, ansible.builtin.find is used to store JSON in the "out" variable and ansible.builtin.debug is used to display the JSON.

---
- hosts: localhost
  tasks:
  - name: store the contents of the /tmp directory in the 'out' variable
    ansible.builtin.find:
      paths: /tmp
    register: out

  - ansible.builtin.debug:
      var: out
...

 

Something like this should be returned.

ok: [localhost] => {
    "out": {
        "changed": false,
        "examined": 1,
        "failed": false,
        "files": [
            {
              "atime": 1583384414.8106842,
              "mtime": 1583388631.5600421,
              "dev": 64768,
              "gid": 0,
              "inode": 131881,
              "isblk": false,
              "ischr": false,
              "isdir": false,
              "isfifo": false,
              "isgid": false,
              "islnk": false,
              "isreg": true,
              "issock": false,
              "isuid": false,
              "mode": "0664",
              "mtime": 158338361.5600421,
              "nlink": 1,
              "path": "/tmp/foo.txt",
              "rgrp": true,
              "roth": true,
              "rusr": true,
              "size": 8,
              "uid": 0,
              "wgrp": false,
              "woth": false,
              "wusr": true,
              "xgrp": false,
              "xoth": false,
              "xusr": false
           }
        ],
        "matched": 1,
        "msg": ""
    }
}

 

Here is how you can print the value of the "changed" key.

---
- hosts: localhost
  tasks:
  - name: store the contents of the /tmp directory in the 'out' variable
    ansible.builtin.find:
      paths: /tmp
    register: out

  - name: print the value in the "changed" key
    ansible.builtin.debug:
      msg: "{{ out.changed }}"
...

 

Which should return something like this.

TASK [determine if 'changed' is true of false] 
ok: [localhost] => {
    "msg": false
}

 

Notce that the "files" key is a list, as incidated by the [ ] (bracket) characters. Here is one way that you could return the value of a key inside the "files" list.

---
- hosts: localhost
  tasks:
  - name: store the contents of the /tmp directory in the 'out' variable
    ansible.builtin.find:
      paths: /tmp
    register: out

  - name: return the value of the path key
    ansible.builtin.debug:
      msg: "{{ out.files[0].path}}"
...

 

Or, you could loop the "files" list.

---
- hosts: localhost
  tasks:
  - name: store the contents of the /tmp directory in the 'out' variable
    ansible.builtin.find:
      paths: /tmp
    register: out

  - name: return the value of the path key
    ansible.builtin.debug:
      msg: "{{ item.path}}"
    with_items: "{{ out.files }}"
...

 

Which should return something like this.

TASK [return the value of the path key] 
ok: [localhost] => {
    "msg": "/tmp/foo.txt"
}

 

Or, json_query could be used.

---
- hosts: localhost
  tasks:
  - name: store the contents of the /tmp directory in the 'out' variable
    ansible.builtin.find:
      paths: /tmp
    register: out

  - name: return the value of the path key
    ansible.builtin.debug:
      var: item
    with_items: "{{ out | json_query('files[*].path') }}"
...

 

Convert a string to a dict using from_json or convert a dict to a string using to_json

There may also be scenarios where you are fetching JSON or a dictionary from something outside of Ansible. For example, perhaps you are using ansible.builtin.shell to run a homegrown script that returns JSON or a dictionary. For example, something like this.

---
- hosts: localhost
  tasks:
  - name: invoke homegrown script.py
    ansible.builtin.shell: /path/to/homegrown/script.py
    register: out
    
  - ansible.builtin.debug:
      var: out.stdout

 

Let's say the above playbook returns the following, which means that the homegrown script returned JSON or a dictionary.

ok: [localhost] => {
    "out": {
        "result": "success",
        "data": "hello world",        
    }
}

 

The type_debug filter can be used to display the type of object that Ansible is registering.

- ansible.builtin.debug:
    var: out.stdout | type_debug

 

Which should return something like this, in this scenario, almost always a str or dict.

ok: [localhost] => {
    "out.stdout | type_debug": "dict"
}

 

Depending on the flavor and version of Ansible that you are using, you may be able to print the values of the keys like this.

- ansible.builtin.debug:
    var: out.stdout.result
    
- ansible.builtin.debug:
    var: out.stdout.data    

 

On the other hand, some flavors or versions of Ansible will require you to use the to_json filter because Ansible is detecting that the out variable is a string and not a dict, thus to_json is needed to convert the out variable from a string to a dict.

- ansible.builtin.debug:
    var: (out.stdout | to_json).result
    
- ansible.builtin.debug:
    var: (out.stdout | to_json).data

 

Or to use from_json to convert the dict to a string.

- ansible.builtin.debug:
    var: (out.stdout | from_json).result
    
- ansible.builtin.debug:
    var: (out.stdout | from_json).data

 




Did you find this article helpful?

If so, consider buying me a coffee over at Buy Me A Coffee



Comments


Add a Comment


Please enter 3be809 in the box below so that we can be sure you are a human.