How to inspect a json response from Ansible URI call
Solution 1
This works for me.
- name: check sonar web is up
uri:
url: http://sonarhost:9000/sonar/api/system/status
method: GET
return_content: yes
status_code: 200
body_format: json
register: result
until: result.json.status == "UP"
retries: 10
delay: 30
Notice that result
is a ansible dictionary and when you set return_content=yes
the response is added to this dictionary and is accessible using json
key
Also ensure you have indented the task properly as shown above.
Solution 2
You've made the right first step by saving the output into a variable.
The next step is to use either when:
or failed_when:
statement in your next task, which will then switch based on the contents of the variable. There are a whole powerful set of statements for use in these, the Jinja2 builtin filters, but they are not really linked well into the Ansible documentation, or summarised nicely.
I use super explicitly named output variables, so they make sense to me later in the playbook :) I would probably write yours something like:
- name: check sonar web is up
uri:
url: http://sonarhost:9000/sonar/api/system/status
method: GET
return_content: yes
status_code: 200
body_format: json
register: sonar_web_api_status_output
- name: do this thing if it is NOT up
shell: echo "OMG it's not working!"
when: sonar_web_api_status_output.stdout.find('UP') == -1
That is, the text "UP" is not found in the variable's stdout.
Other Jinja2 builtin filters I've used are:
changed_when: "'<some text>' not in your_variable_name.stderr"
when: some_number_of_files_changed.stdout|int > 0
The Ansible "Conditionals" docs page has some of this info. This blog post was also very informative.
Solution 3
As per documentation at https://docs.ansible.com/ansible/latest/modules/uri_module.html
Whether or not to return the body of the response as a "content" key in the dictionary result. Independently of this option, if the reported Content-type is "application/json", then the JSON is always loaded into a key called json in the dictionary results.
---
- name: Example of JSON body parsing with uri module
connection: local
gather_facts: true
hosts: localhost
tasks:
- name: Example of JSON body parsing with uri module
uri:
url: https://jsonplaceholder.typicode.com/users
method: GET
return_content: yes
status_code: 200
body_format: json
register: data
# failed_when: <optional condition based on JSON returned content>
- name: Print returned json dictionary
debug:
var: data.json
- name: Print certain element
debug:
var: data.json[0].address.city
Hafiz
Updated on April 05, 2020Comments
-
Hafiz about 4 years
I have a service call that returns system status in
json
format. I want to use the ansible URI module to make the call and then inspect the response to decide whether the system is up or down{"id":"20161024140306","version":"5.6.1","status":"UP"}
This would be the
json
that is returnedThis is the ansible task that makes a call:
- name: check sonar web is up uri: url: http://sonarhost:9000/sonar/api/system/status method: GET return_content: yes status_code: 200 body_format: json register: data
Question is how can I access
data
and inspect it as per ansible documentation this is how we store results of a call. I am not sure of the final step which is to check the status. -
Hafiz over 7 yearsposted about the same time as my answer :) so now I am not sure which one to mark as correct answer as both seem to work
-
ocean over 7 yearsHehe ok :) Sorry I took a bit to write that.
-
ocean over 7 yearsThis is nice, the fact that result comes in as an Ansible dictionary and there's a Jinja2 JSON parser already there to extract info from it.
-
TJA over 4 years@Halfiz Thank you, thank you, thank you. My until: condition was not working and it was the indentation that was biting me.
-
AhmFM over 4 yearshow to say the site is UP by looking at status_code?
-
HermanTheGermanHesse over 4 years
register
is too indented, it needs to spaces less