I'm new to Ansible and just having a problem with variables in inventory. In the inventory I have different variables which contain MAC or IP addresses. I want to loop through them and, if they are present, process them in a jinjar2 template.
My inventory (shortened):
net6_prd:
children:
net6_prd_test:
hosts:
net6-tst-01:
eth1_mac: "001 eth1 mac"
eth1_ip: "001 eth1 ip"
eth2_mac: "001 eth2 mac"
eth2_ip: "001 eth2 ip"
net6-tst-02:
eth1_mac: "002 eth1 mac"
eth1_ip: "002 eth1 ip"
eth2_mac: "002 eth2 mac"
eth2_ip: "002 eth2 ip"
In the jinjar2 template I use the following loop:
{% for ihost in hostvars -%}
# example={{ hostvars[items]['eth1_mac'] }}
{% endfor %}
Unfortunately, this does not work. Ansible reports that the variable does not exist.
FAILED! => {"changed": false, "msg": "AnsibleUndefinedVariable: 'ansible.vars.hostvars.HostVarsVars object' has no attribute 'eth1_mac'"}
I have also tried to run via groups[net6_prd]
over all host in net6_prd
, but this doesn't work either. Anyone else have any ideas what is wrong with my loop?
The variable hostvars
actually contains all the hosts, regardless if they are targeted by the play or not. That's why you might encounter this issue, you probably have hosts that do not have those variables defined in your inventory.
Based on which host(s) you do want to loop over, you can use:
ansible_play_hosts
special variable, which
List of hosts in the current play run, not limited by the serial. Failed/Unreachable hosts are excluded from this list.
groups['net6_prd_test']
, which will list all hosts in the group called net6_prd_test
So you end up, going, in your template:
{% for _host in ansible_play_hosts %}
# example={{ hostvars[_host].eth1_mac }}
{% endfor %}
If you really cannot avoid targeting hosts with those undefined variable, you can also filter in your loop:
{% for _host in hostvars if hostvars[_host].eth1_mac is defined %}
# example={{ hostvars[_host].eth1_mac }}
{% endfor %}