# Json\_query/jmespath help with JSON output of ansible-playbook execution

**URL:** <https://forum.ansible.com/t/json-query-jmespath-help-with-json-output-of-ansible-playbook-execution/39733>\
**Category:** Get Help\
**Tags:** json, jmespath, ansible\
**Created:** [January 21, 2025, 12:14pm UTC](https://forum.ansible.com/t/json-query-jmespath-help-with-json-output-of-ansible-playbook-execution/39733 "2025-01-21T12:14:12Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![iamroddo](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/iamroddo/32/321_2.png) [@iamroddo](https://forum.ansible.com/u/iamroddo)\
**Post date:** [January 21, 2025, 12:14pm UTC](https://forum.ansible.com/t/json-query-jmespath-help-with-json-output-of-ansible-playbook-execution/39733/1 "2025-01-21T12:14:13Z")

</div>

I am looking to do some meta analysis of the execution of a playbook by setting `stdout_callback = json` in `ansible.cfg` and analysing the output.

Specifically I’d like to extract a list of tasks and whether for each host the task changed anything. AFAIK that should be expressed by the value of `changed` under the host and task. I was hoping to use Ansible + json\_query i.e. a jmespath filter to extract this information.

I see that the output looks like that below:

```json
{
    "plays": [
        {
            "play": {
                "name": "Play 1"
            },
            "tasks": [
                {
                    "hosts": {
                        "host1": {
                            "changed": true
                        },
                        "host2": {
                            "changed": false
                        }
                    },
                    "task": {
                        "name": "Task 1"
                    }
                }
            ]
        }
    ]
}

```

My desired extraction:

```json
[
  {
    "task": "Task 1",
    "hosts": [
        "host1"
    ]
  }
]

```

I’ve got as far as `plays[].tasks[].{task: task.name, hosts: keys(hosts) | [?hosts[?@] ==`true`]}` but that doesn’t work (as tested in [https://play.jmespath.org/](https://play.jmespath.org/)). I’m not sure how to filter the hosts based on the value of `changed` and display the host name. Any help would be appreciated.

---

<div class="post-metadata">

**Author:** ![chris](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/chris/32/293_2.png) [@chris](https://forum.ansible.com/u/chris)\
**Post date:** [January 21, 2025, 12:52pm UTC](https://forum.ansible.com/t/json-query-jmespath-help-with-json-output-of-ansible-playbook-execution/39733/2 "2025-01-21T12:52:44Z")

</div>

I did this a while ago for running Ansible using the [chroot\_connection](https://docs.ansible.com/ansible/latest/collections/community/general/chroot_connection.html) on remote servers, I [used](https://git.coop/webarch/chroot-config/-/blob/b7abd5e84acf0073a825a1995396507fc508b37b/ansible.cfg) `stdout_callback = ansible.posix.json` and run the roles in a loop using [the task here](https://git.coop/webarch/chroot/-/blob/26573de736e6ce76a260a717bcc9d00059438163/tasks/role.yml) and then I used another loop on the results to get the tasks that changed, I expect this isn’t the most elegant solution but it works!

This is the include:

```yaml
- name: Include /root/chroot-config/run.sh task for each role to configure the chroot
  ansible.builtin.include_tasks: role.yml
  loop: "{{ chroot_config_playbook_roles }}"
  loop_control:
    loop_var: chroot_config_role

```

And these are the tasks in `role.yml`:

```yaml
- name: "Run the chroot.yml playbook for role {{ chroot_config_role }}" 
  ansible.builtin.command: "ansible-playbook -i hosts.yml -c chroot chroot.yml --tags {{ chroot_config_role }}" 
  args:
    chdir: /root/chroot-config
  environment:
    ANSIBLE_CONFIG: "/root/chroot-config/ansible.cfg"
    ANSIBLE_NOCOWS: "1" 
    DEBIAN_FRONTEND: "noninteractive"
    PATH: "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
  vars:
    chroot_role_changed_jpquery: 'stats.["{{ chroot_dir }}"]|[0].changed'
  register: chroot_role_run
  changed_when: chroot_role_run.stdout | from_json | json_query(chroot_role_changed_jpquery) != 0

- name: "Tasks changed for role {{ chroot_config_role }}" # noqa no-handler
  ansible.builtin.debug:
    msg: "{{ chroot_role_task | json_query('task.name') }}" 
  changed_when: false
  when: chroot_role_task | json_query('hosts.*.changed|[0]') | lower | bool
  loop: "{{ chroot_role_run.stdout | from_json | json_query('plays[0].tasks') }}" 
  loop_control:
    extended: true
    label: "Task {{ ansible_loop.index }}" 
    loop_var: chroot_role_task

```
