Ansible - Loop through JSON array

When using the register parameter, the output is almost always returned as JSON. Here is an example of using the register parameter with the find module.

- find:
    paths: /tmp
  register: out

 

The debug module can be used to print the JSON.

- debug:
    var: out

 

Which should return something like this.

ok: [server1.example.com] => {
    "out": {
        "changed": false,
        "examined": 1,
        "failed": false,
        "files": [],
        "matched": 0,
        "msg": ""
    }
}

 

Let's say you only want to print the "matched" key.

- debug:
    var: out.matched

 

Which should return something like this.

ok: [server1.example.com] => {
    out.matched: 0
}

 


Array

Let's say the following JSON is returned. Notice here that the "files" key is an array, as indicated by the [ ] brackets.

ok: [server1.example.com] => {
    "out": {
        "files": [
            {
              "path": "/tmp/foo.txt",
           }
            {
              "path": "/tmp/bar.txt",
           }
        ],
    }
}

 

One option is to do something like this. Index 0 is used to enter the first "files" key. If there were another "files" key, then index 1 would be used for the following files key.

- debug:
    msg: "{{ out.files[0].path}}"

 

Or you could loop over the files array.

- debug:
    msg: "{{ item.path }}"
  with_items: "{{ out.files }}"

 

Which should return something like this.

ok: [server1.example.com] => {
    "msg": "/tmp/foo.txt"
}

ok: [server1.example.com] => {
    "msg": "/tmp/bar.txt"
}

 

Or like this.

- debug:
    msg: "{{ items }}"
  vars:
    items: "{{ out.files | map(attribute='path') | list }}"

 

Which should return something like this.

ok: [server1.example.com] => {
    "msg": [
        "/tmp/foo.txt",
        "/tmp/bar.txt"
    ]
}

 


loop / with_items

Let's say you are using the loop or with_items parameter.

- find:
    paths: /tmp
  with_items: [ foo, bar ]
  register: out

 

In this scenario, the JSON that is returned will begin with the "results" array and the "item" key.

ok: [server1.example.com] => {
    "out": {
        "results": [
            "item": "foo",
            "files": [
                {
                  "path": "/tmp/foo.txt",
               }
                {
                  "path": "/tmp/bar.txt",
               }
            ],
            "item": "bar",
            "files": [
                {
                  "path": "/tmp/foo.txt",
               }
                {
                  "path": "/tmp/bar.txt",
               }
            ]
        ]
    }
}

 



Add a Comment




We will never share your name or email with anyone. Enter your email if you would like to be notified when we respond to your comment.





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




Comments


January 23rd, 2022 by Pavel
Thank you very much. I've read tons of posts and docs trying to iterate through uri module results, but your article was the one that showed the correct and simple (!) way.

Web design by yours truely - me, myself, and I   |   jeremy.canfield@freekb.net   |