# json\_query/jmespath filtering question

**URL:** <https://forum.ansible.com/t/json-query-jmespath-filtering-question/32437>\
**Category:** Ansible Project\
**Created:** [March 10, 2020, 8:31pm UTC](https://forum.ansible.com/t/json-query-jmespath-filtering-question/32437 "2020-03-10T20:31:41Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![nschende](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/nschende/32/1681_2.png) [@nschende](https://forum.ansible.com/u/nschende)\
**Post date:** [March 10, 2020, 8:31pm UTC](https://forum.ansible.com/t/json-query-jmespath-filtering-question/32437/1 "2020-03-10T20:31:41Z")

</div>

Trying to wrap my head about how to query json results from a URI call & could use some guidance. I am guessing there are plenty in this group which this will be an easy question for.

I am registering the json response from a URI call to our backup system to ‘snapshotlist’

Here is an example chunk of the json:

“json”: {  
“vmwareTagList”: ,  
“isCorrupt”: false,  
“snapshotDiskDetails”: [  
{  
“virtualDiskId”: “23478e90-0228-4tab-ba99-d3894f94c8c837-vm-98-2001”,  
“deviceKey”: 2001,  
“size”: 214748364800,  
“id”: “83fecf84-26db-42db-9f33-ec7e10b5f736”,  
“fileName”: “[DC1\_LINUX\_VM\_STORAGE] host2restore/host2restore\_1.vmdk”  
},  
{  
“virtualDiskId”: “23478e90-0228-4tab-ba99-d3894f94c8c837-vm-98-2002”,  
“deviceKey”: 2002,  
“size”: 214748364800,  
“id”: “1a9c094f-f19b-4ea7-1406-ab145b0ec2f1”,  
“fileName”: “[DC1\_LINUX\_VM\_STORAGE] host2restore/host2restore\_2.vmdk”  
},  
{  
“virtualDiskId”: “23478e90-0228-4tab-ba99-d3894f94c8c837-vm-98-2000”,  
“deviceKey”: 2000,  
“size”: 42949672960,  
“id”: “83182b0a-bc21-4ef8-8582-7ec95465380b”,  
“fileName”: “[DC1\_LINUX\_VM\_STORAGE] host2restore/host2restore.vmdk”  
}  
],  
“date”: “2020-03-10T05:42:32.675Z”,  
“cloudState”: 0,

I am trying to get the value of “id” for the object with fileName that ends with host2retore\_1.vmdk

This is what I currently have to try to pull that value out based on some example I found on a blog somewhere. However I get errors. Anyone able to help me figure out what I am doing wrong?

- name: set variable for disk\_snap\_id  
set\_fact:  
disk\_snap\_id: “{{ json\_query(‘snapshotdetails.json.snapshotDiskDetails[?fileName.contains(@, ‘host2restore\_1.vmdk’)].virtualDiskId’) }}”

---

<div class="post-metadata">

**Author:** ![Dick\_Visser](https://avatars.discourse-cdn.com/v4/letter/d/d9b06d/32.png) [@Dick\_Visser](https://forum.ansible.com/u/Dick_Visser)\
**Post date:** [March 10, 2020, 9:04pm UTC](https://forum.ansible.com/t/json-query-jmespath-filtering-question/32437/2 "2020-03-10T21:04:45Z")

</div>

You need to filter a variable through json\_query.

Also, I don’t see any key called ‘snapshotdetails’.  
And that json string should be filtered through from\_json, ideally.

It looks like your “json” var isn’t really what you are using.  
If I shuffle things around slightly, then below playbook works:

---

<div class="post-metadata">

**Author:** ![nschende](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/nschende/32/1681_2.png) [@nschende](https://forum.ansible.com/u/nschende)\
**Post date:** [March 10, 2020, 9:15pm UTC](https://forum.ansible.com/t/json-query-jmespath-filtering-question/32437/3 "2020-03-10T21:15:54Z")

</div>

Oops I said the wrong register variable name in my question. snapshotlist is the registered output of a previous task, snapshotdetails is the register of the task right before this particular task. the chunk of json I pasted in is pulled from the previous task’s output.  
I was previously able to use snapshotdetails.json.snapshotDiskDetails[1].virtualDiskId to get a value in the play, it was the filtering that I have been struggling with.

Thanks for the reply I will give that a shot.

---

<div class="post-metadata">

**Author:** ![nschende](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/nschende/32/1681_2.png) [@nschende](https://forum.ansible.com/u/nschende)\
**Post date:** [March 11, 2020, 10:24pm UTC](https://forum.ansible.com/t/json-query-jmespath-filtering-question/32437/4 "2020-03-11T22:24:39Z")

</div>

Still struggling to get this working. Posting my entire playbook in case it can help understand what I might be doing wrong:

- hosts: ‘{{inventory\_hostname}}’  
gather\_facts: no  
vars:  
cluser\_ip: “{{ rubrik\_hostname }}”

tasks:

- name: login to rubrik to generate token  
uri:  
url: https://{{ cluser\_ip }}/api/v1/session # URL to generate an auth token to be used by subsequent calls  
force\_basic\_auth: yes  
user: ‘{{ lookup(“env”, “rubrik\_username”) }}’  
password: ‘{{ lookup(“env”, “rubrik\_password”) }}’  
method: POST  
status\_code: 200  
return\_content: yes  
validate\_certs: yes  
register: authtoken # token is available as authtoken.json.token  
delegate\_to: localhost  
become: no

- name: get target vm id  
uri:  
url: https://{{ cluser\_ip }}/api/v1/vmware/vm?name={{ inventory\_hostname\_nfq }}  
headers:  
Content-Type: “application/json”  
Authorization: “Bearer {{ authtoken.json.token }}” # pass authentication token from earlier rather than basic auth  
method: GET  
status\_code: 200  
return\_content: yes  
validate\_certs: yes  
register: vminfo  
delegate\_to: localhost  
become: no

- name: set variable for target\_vm\_id  
set\_fact:  
target\_vm\_id: “{{ vminfo.json.data[0].id }}”

- name: get list of snapshots  
uri:  
url: https://{{ cluser\_ip }}/api/v1/vmware/vm/{{ source\_vm\_id }}/snapshot  
headers:  
Content-Type: “application/json”  
Authorization: “Bearer {{ authtoken.json.token }}” # pass authentication token from earlier rather than basic auth  
method: GET  
status\_code: 200  
return\_content: yes  
register: snapshotlist  
delegate\_to: localhost  
become: no

- name: get info on the snapshot to be used  
uri:  
url: https://{{ cluser\_ip }}/api/v1/vmware/vm/snapshot/{{ snapshotlist.json.data[0].id }}  
headers:  
Content-Type: “application/json”  
Authorization: “Bearer {{ authtoken.json.token }}” # pass authentication token from earlier rather than basic auth  
method: GET  
status\_code: 200  
return\_content: yes  
register: snapshotdetails  
delegate\_to: localhost  
become: no

- name: set variable for disk\_snap\_id  
set\_fact:  
disk\_snap\_id: “{{ snapshotdetails | from\_json | json\_query(‘json.snapshotDiskDetails[?fileName.contains(@, ‘host2restore\_1’)].virtualDiskId’) }}”

Error I am getting currently:

TASK [set variable for disk\_snap\_id] \*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*\*  
**task path: /tmp/awx\_56722\_7ypjkkvu/project/oracle\_refresh\_fixorder.yml:67**  
fatal: [host2]: FAILED! =\> {  
“msg”: “template error while templating string: expected token ‘,’, got ‘host2restore\_1’. String: {{ snapshotdetails | from\_json | json\_query(‘json.snapshotDiskDetails[?fileName.contains(@, ‘host2restore\_1’)]’) }}”  
}

I also attempted setting the actual query string in a separate var, and passing that to the json\_query as I have seen in many examples but that also did not work. not sure what I am doing wrong. A few permutations I have tried have run successfully but then returned a blank value. As you can see from the playbook snapshotdetails is a registered variable from the previous task.

---

<div class="post-metadata">

**Author:** ![Dick\_Visser](https://avatars.discourse-cdn.com/v4/letter/d/d9b06d/32.png) [@Dick\_Visser](https://forum.ansible.com/u/Dick_Visser)\
**Post date:** [March 11, 2020, 10:31pm UTC](https://forum.ansible.com/t/json-query-jmespath-filtering-question/32437/5 "2020-03-11T22:31:57Z")

</div>

The query for json\_query is between single quotes. But you also use  
single quotes to quote 'host2restore\_1' - that doesn't work.  
You need to use backticks instead.  
If you look closely you can see that those were in the previous  
example. I agree that it's not easy to spot 🙂

Dick

---

<div class="post-metadata">

**Author:** ![nschende](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/nschende/32/1681_2.png) [@nschende](https://forum.ansible.com/u/nschende)\
**Post date:** [March 11, 2020, 11:01pm UTC](https://forum.ansible.com/t/json-query-jmespath-filtering-question/32437/6 "2020-03-11T23:01:15Z")

</div>

Yup I absolutely did not notice that, thank you for pointing it out. now I am getting the following error:

fatal: [host2]: FAILED! =\> {  
“msg”: “Unexpected templating type error occurred on ({{ snapshotdetails | from\_json | json\_query(‘json.snapshotDiskDetails[?fileName.contains(@, `host2restore_1`)].virtualDiskId’) }}): expected string or buffer”  
}

---

<div class="post-metadata">

**Author:** ![Dick\_Visser](https://avatars.discourse-cdn.com/v4/letter/d/d9b06d/32.png) [@Dick\_Visser](https://forum.ansible.com/u/Dick_Visser)\
**Post date:** [March 11, 2020, 11:30pm UTC](https://forum.ansible.com/t/json-query-jmespath-filtering-question/32437/7 "2020-03-11T23:30:29Z")

</div>

Can you put a debug task between the uri and set\_fact tasks and post  
what that outputs?

- debug: var=snapshotdetails

If you put this in your ansible.cfg then it's more readable:

stdout\_callback = yaml  
bin\_ansible\_callbacks = True

---

<div class="post-metadata">

**Author:** ![nschende](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/nschende/32/1681_2.png) [@nschende](https://forum.ansible.com/u/nschende)\
**Post date:** [March 11, 2020, 11:39pm UTC](https://forum.ansible.com/t/json-query-jmespath-filtering-question/32437/8 "2020-03-11T23:39:44Z")

</div>

managed to get it working with this:

- name: set variable for disk\_snap\_id  
set\_fact:  
disk\_snap\_id: “{{ snapshotdetails | to\_json | from\_json | json\_query(‘json.snapshotDiskDetails[?fileName.contains(@, `host2restore_1`)].virtualDiskId’) }}”

after finding this:

[https://stackoverflow.com/questions/48318708/unexpected-templating-type-error-occured-on-ec2-instances-from-json-exp](https://stackoverflow.com/questions/48318708/unexpected-templating-type-error-occured-on-ec2-instances-from-json-exp)
