首页 > 解决方案 > Ansible use return value as dictionary

问题描述

I have seen similar questions but something is not clicking with me.

I have a custom module that I wrote which parses data from an API and I want to use the results of the module as a dictionary in my playbook (to be referenced by subsequent tasks).

Once I have the data, I use a module like so:

- name: build ditionary of system ip's
  device_vars_builder:
    DEV_OUT: "{{ DEVICE_LIST }}"
  register: DEVICE_RESULT

A debug on DEVICE_RESULT.msg_output looks like this:

ok: [localhost] => {
    "msg": [
        "{ name: 'TEST1_HOST', ip_addr: '1.1.1.1' }", 
        "{ name: 'TEST2_HOST', ip_addr: '1.1.1.2' }"
    ]
}

However if I use Loop or

- name: iterate items
  debug:
    msg: '{{ item.name }}'
  with_items: DEVICE_RESULT.msg_output

I get an error 'ansible.utils.unsafe_proxy.AnsibleUnsafeText object' has no attribute 'name'

I also tried converting the result using set_fact thinking it was not being recognized as a dictionary:

- name: Populate dictionary with items
  set_fact:
    DEVICE_DATA: "{{ DEVICE_DATA|default([]) +  [ item ] }}"
  with_items: "{{ DEVICE_RESULT.msg_output }}"

Anyone have any suggestions on how I can use the result as a dictionary? With the python script I can make the output as ansible friendly as I need to.

Thanks!

标签: pythonansibleansible-facts

解决方案


您缺少以下扩展with_items

- name: iterate items
  debug:
    msg: "{{ item.name }}"
  with_items: DEVICE_RESULT.msg_output

应该:

- name: iterate items
  debug:
    msg: "{{ item.name }}"
  with_items: "{{ DEVICE_RESULT.msg_output }}"

下面是一个使用 Python 3.6.4 和 Ansible 2.6.0 的工作示例:

播放.yml

---

- hosts: localhost
  tasks:
    - name: build dictionary of system ips
      custommod:
      register: DEVICE_RESULT

    - debug:
        var: DEVICE_RESULT

    - name: iterate items
      debug:
        msg: "{{ item.name }}"  # You need double quotes here
      with_items: "{{ DEVICE_RESULT.msg }}"  # And double quotes here

库/custommod.py

#!/usr/bin/python
# -*- coding: utf-8 -*-
from ansible.module_utils.basic import *


def main():
    module = AnsibleModule({})
    l = [
            { 'name': 'TEST1_HOST', 'ip_addr': '1.1.1.1' },
            { 'name': 'TEST2_HOST', 'ip_addr': '1.1.1.2' },
        ]

    module.exit_json(changed=True, msg=l)


if __name__ == '__main__':
    main()

输出

ansible-playbook play.yml
 [WARNING]: Unable to parse /etc/ansible/hosts as an inventory source

 [WARNING]: No inventory was parsed, only implicit localhost is available

 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'


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

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

TASK [build ditionary of system ip's] **********************************************************************************************************************************************
changed: [localhost]

TASK [debug] ***********************************************************************************************************************************************************************
ok: [localhost] => {
    "DEVICE_RESULT": {
        "changed": true,
        "failed": false,
        "msg": [
            {
                "ip_addr": "1.1.1.1",
                "name": "TEST1_HOST"
            },
            {
                "ip_addr": "1.1.1.2",
                "name": "TEST2_HOST"
            }
        ]
    }
}

TASK [iterate items] ***************************************************************************************************************************************************************
ok: [localhost] => (item={'name': 'TEST1_HOST', 'ip_addr': '1.1.1.1'}) => {
    "msg": "TEST1_HOST"
}
ok: [localhost] => (item={'name': 'TEST2_HOST', 'ip_addr': '1.1.1.2'}) => {
    "msg": "TEST2_HOST"
}

PLAY RECAP *************************************************************************************************************************************************************************
localhost                  : ok=4    changed=1    unreachable=0    failed=0

推荐阅读