14

I have an Ansible task that makes a URI request to a website to get a JSON response. I want Ansible to do something if the nested JSON variable is defined, and something else if it isn't.

- name: Get JSON from the Interwebs
  uri: url="http://whatever.com/jsonresponse" return_content=yes
  register: json_response

- name: Write nested JSON variable to disk
  copy: content={{json_response.json.nested1.nested2}} dest="/tmp/foo.txt"

Note that using ignore_errors only works for the task's command failing, not for checking undefined values in nested data structures within a Jinja template. So if json_response.json.nested1.nested2 isn't defined, this task will still fail despite ignore_errors=yes being set.

How do I get this playbook to store some default value in /tmp/foo.txt if the request fails, or if the request doesn't have the right nested value defined?

19

You need to use a jinja2 filter (http://docs.ansible.com/ansible/playbooks_filters.html). In this case, the name of the filter is from_json. In the following example I'll take an action when the key is found and other action when the could not be found:

 ---                                                                                                            

 - hosts: somehost                                                                                               
   sudo: yes                                                                                                    

   tasks:                                                                                                       

   - name: Get JSON from the Interwebs                                                                          
     uri: url="https://raw.githubusercontent.com/ljharb/node-json-file/master/package.json" return_content=yes  
     register: json_response                                                                                    

   - debug: msg="Error - undefined tag"                                                                         
     when: json_response["non_existent_tag"] is not defined                                                     

   - debug: msg="Success - tag defined =>{{  (json_response.content|from_json)['scripts']['test'] }}<="  
     when:  (json_response.content|from_json)['scripts']['test']  is defined    

Now replace the debug for the appropriate to take the desired action.

Hope it helps,

3

I stumbled here after looking for a way on how to extract a field from json from the github api. I ended up with the following solution.

uri: url="https://api.github.com/repos/.../.../releases/latest" return_contents=yes

register: github_json

and use it somewhere else like this:

"{{ github_json.json.$key }}"
  • 1
    I am not sure this actually helps the OP: you don't really explain where $key comes from, and the question is basically asking what happens when there is no $key field in the response - i.e. something jinja's default filter might be useful for. – iwaseatenbyagrue Apr 10 '17 at 16:42
  • 1
    This wasn't a direct response to the OP since the question is more than a year and half old but I was hoping it could be helpful for people that wanted to get JSON values from an API using only Ansible which is how I stumbled on this page. – Samy Coenen Apr 11 '17 at 18:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.