Loop over json objects in Ansible
Ansible's json_query filter let's you perform complex filtering of JSON documents by applying JMESPath expressions. Rather than looping over the jobs in the the result, you can get the information you want in a single step.
We want to query all jobs in which have a destClientName
that matches the value in target_vm
. Using literal values, the expression yielding that list of jobs would look like this:
jobs[?jobSummary.destClientName == `BOSDEKARLSSP006`]
The result of this, when applied to your sample data, would be:
[ { "jobSummary": { "totalNumOfFiles": 0, "jobId": 9629, "destClientName": "BOSDEKARLSSP006", "destinationClient": { "clientId": 11, "clientName": "BOSDEKARLSSP006" } } }]
From this result, you want to extract the jobId
, so we rewrite the expression like this:
jobs[?jobSummary.destClientName == `BOSDEKARLSSP006`]|[0].jobSummary.jobId
Which gives us:
9629
To make this work in a playbook, you'll want to replace the literal hostname in this expression with the value of your target_vm
variable. Here's a complete playbook that demonstrates the solution:
---- hosts: localhost gather_facts: false # This is just the sample data from your question. vars: target_vm: BOSDEKARLSSP006 results: totalRecordsWithoutPaging: 1234 jobs: - jobSummary: totalNumOfFiles: 0 jobId: 8035 destClientName: BOSDEKARLSSP010 destinationClient: clientId: 10 clientName: BOSDEKARLSSP010 - jobSummary: totalNumOfFiles: 0 jobId: 9629 destClientName: BOSDEKARLSSP006 destinationClient: clientId: 11 clientName: BOSDEKARLSSP006 tasks: - name: get job ID set_fact: job_id: "{{ results|json_query('jobs[?jobSummary.destClientName == `{}`]|[0].jobSummary.jobId'.format(target_vm)) }}" - debug: var: job_id
Update re: your comment
The {}
in the expression is a Python string formatting sequence thatis filled in by the call to .format(target_vm)
. In Python, theexpression:
'The quick brown {} jumped over the lazy {}.'.format('fox', 'dog')
Would evaluate to:
The quick brown fox jumped over the lazy dog.
And that's exactly what we're doing in that set_fact
expression. Icould instead have written:
job_id: "{{ results|json_query('jobs[?jobSummary.destClientName == `' ~ target_vm ~ '`]|[0].jobSummary.jobId') }}"
(Where ~
is the Jinja stringifying concatenation operator)