Reputation: 75
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!
Upvotes: 1
Views: 4185
Reputation: 6058
You are missing expansion on your with_items
:
- name: iterate items
debug:
msg: "{{ item.name }}"
with_items: DEVICE_RESULT.msg_output
Should be:
- name: iterate items
debug:
msg: "{{ item.name }}"
with_items: "{{ DEVICE_RESULT.msg_output }}"
Below is a working example using Python 3.6.4 & Ansible 2.6.0:
---
- 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
#!/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
Upvotes: 3