Matthew Wimpelberg
Matthew Wimpelberg

Reputation: 27

loop through variable in Ansible

I'm trying to fetch multiple spring health urls and print out the results. When I run this playbook with one single URL I can print data.json.status to get the output of the uri request.

# ansible --version
ansible 2.9.7
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Apr  2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
---
- hosts: localhost
  ignore_errors: true
  tasks:
    - name: check health
      uri:
        url: <REDACTED>
        method: GET
        validate_certs: no
        return_content: yes
        status_code: 200
        body_format: json
      register: data

    - name: print result
      debug: 
        msg: "{{ data.json.status }}"
# ansible-playbook 1healthcheck.yml                                                                                                                                                                                   

PLAY [localhost] *****************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [check health] **************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [print result] **************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": "UP"
}

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

The trouble is when I add in a loop to process multiple urls.

---
- hosts: localhost
  ignore_errors: true
  vars_files:
    - ./healthchecks.yml
  tasks:
    - name: check health
      uri:
        url: api
        method: GET
        validate_certs: no
        return_content: yes
        status_code: 200
        body_format: json
      register: data
      with_items:
        - "{{ urls }}"

    - name: Print json status for each item
      debug: 
        msg: "{{ item.json.status }}"
      with_items: "{{ data }}"
# ansible-playbook healthcheck.yml 

PLAY [localhost] *****************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [check health] **************************************************************************************************************************************************************************************************************************
failed: [localhost] (item=<REDACTED>) => {"ansible_loop_var": "item", "changed": false, "item": "<REDACTED>", "msg": "unknown url type: api", "status": -1, "url": "api"}
...ignoring

TASK [Print json status for each item] *******************************************************************************************************************************************************************************************************
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'ansible.utils.unsafe_proxy.AnsibleUnsafeBytes object' has no attribute 'json'\n\nThe error appears to be in '/root/healthcheck.yml': line 19, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n    - name: Print json status for each item\n      ^ here\n"}
...ignoring

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=2   

I think that I just need to get a handle on the data structures being used by Ansible. Is the {{{ data }} variable when I use a loop just storing a list? If so how can I print just the .json.status of each item in the list?

Upvotes: 0

Views: 2106

Answers (1)

β.εηοιτ.βε
β.εηοιτ.βε

Reputation: 39304

When you are doing a loop on a tasks, the results ends up in the dictionary key results as pointed by the documentation.

So your debug should be a loop on data.results:

- name: Print json status for each item
  debug: 
    msg: "{{ item.json.status }}"
  loop: "{{ data.results }}"

Note: you can debug a whole data structure like a dictionary or a list in order to figure out what your issue is.
This can be done two ways:

  • either
    - debug:
         var: data
    
  • or
    - debug:
         msg: "{{ data }}"
    

Upvotes: 1

Related Questions