首页 > 解决方案 > 循环遍历 Ansible 中的变量

问题描述

我正在尝试获取多个春季健康网址并打印出结果。当我使用一个 URL 运行此剧本时,我可以打印 data.json.status 以获取 uri 请求的输出。

# 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   

问题是当我添加一个循环来处理多个 url 时。

---
- 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   

我认为我只需要掌握 Ansible 使用的数据结构。{{{ data }}当我使用循环时,变量只是存储一个列表吗?如果是这样,我怎样才能只打印.json.status列表中每个项目的?

标签: linuxapirestansibleansible-2.x

解决方案


当您对任务执行循环时,结果最终会出现在results 文档中指出的字典键中

所以你的调试应该是一个循环data.results

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

注意:您可以debug使用字典或列表等整个数据结构来找出您的问题。
这可以通过两种方式完成:

  • 任何一个
    - debug:
         var: data
    
  • 或者
    - debug:
         msg: "{{ data }}"
    

推荐阅读