I'm hoping to get some guidance on the following code which involves a nested variable in Ansible. Here's the playbook:
---
- name: Testing
hosts: localhost
connection: local
gather_facts: false
vars:
hostname: HOST1
VLAN_DEFS: [
{
"TAG": "1001",
"HOST1_DATA_IP": "10.10.0.1",
"HOST2_DATA_IP": "10.20.0.1",
"DATA_NETMASK": "24"
},
{
"TAG": "1002",
"HOST1_DATA_IP": "10.10.0.2",
"HOST2_DATA_IP": "10.20.0.2",
"DATA_NETMASK": "24"
},
{
"TAG": "1003",
"HOST1_DATA_IP": "10.10.0.3",
"HOST2_DATA_IP": "10.20.0.3",
"DATA_NETMASK": "24"
}
]
tasks:
- template:
src: ./test.j2
dest: ./output.json
And here is the test.j2 Jinja template:
[
{% for VLAN in VLAN_DEFS %}
{
"VLAN": "VLAN{{ VLAN.TAG }}",
"ADDRESS": "{{ lookup('vars', 'VLAN.' ~ hostname ~ '_DATA_IP') }}/{{ VLAN.DATA_NETMASK }}"
}{% if not loop.last %},{% endif %}
{% endfor %}
]
The lookup line I'm using appears to give me what I want which is VLAN.HOST1_DATA_IP, but it's not being interpreted as a valid variable. The result of my playbook is the error "No variable found with this name: VLAN.HOST1_DATA_IP." However, if I replace the ADDRESS line with that exact value as illustrated below, it works fine:
"ADDRESS": "{{ VLAN.HOST1_DATA_IP }}/{{ VLAN.DATA_NETMASK }}"
Does anyone by chance have some insight into why this error is occurring?
You don't need to use a vars
lookup. Instead of var.attribute
, use var[attribute]
, which allows to build the attribute name with an expression, like this:
[
{% for VLAN in VLAN_DEFS %}
{
"VLAN": "VLAN{{ VLAN.TAG }}",
"ADDRESS": "{{ VLAN[hostname ~ '_DATA_IP'] }}/{{ VLAN.DATA_NETMASK }}"
}{% if not loop.last %},{% endif %}
{% endfor %}
]
Which produces:
[
{
"VLAN": "VLAN1001",
"ADDRESS": "10.10.0.1/24"
}, {
"VLAN": "VLAN1002",
"ADDRESS": "10.10.0.2/24"
}, {
"VLAN": "VLAN1003",
"ADDRESS": "10.10.0.3/24"
}
]