Ansible playbook hostvars undefined variables

Folks, The following code is producing errors.

code:

{% for v in hostvars.iteritems() %}
    {{ v['ansible_all_ipv4_addresses'][0] }}  {{ v['ansible_hostname'] }}
{% endfor %}

error:

{'msg': "One or more undefined variables: 'tuple object' has no attribute 'ansible_all_ipv4_addresses'", 'failed': True}

What should this look like if i wanted an /etc/hosts file like:

192.168.111.222 hostnameA
192.168.111.211 hostnameB
...

Thanks!

iteritems() returns a tuple so you need to assign two variables: {% for k,v in hostvars.iteritems() %} {{ k }} {{ v[‘ansible_all_ipv4_addresses’][0] }} {{ v[‘ansible_hostname’] }} {% endfor %} “k” will be the inventory hostname and “v” will be all of the vars for k. Example output: jtanner@u1304:~$ cat /tmp/vadata.txt localhost 192.168.1.105 u1304

James,
The following is breaking as well:

{% for k,v in hostvars.iteritems() %}
{{ v[‘ansible_all_ipv4_addresses’][0] }} {{ v[‘ansible_hostname’] }}
{% endfor %}

Let’s see your playbook. I have a feeling that you aren’t gathering facts.

Are you gathering facts?

Do those facts show ansible_all_ipv4_addresses? This is not present on all distros, for example fails to populate on my gentoo machines.

ansible -m setup |less, will give you a full view of supported facts on the target.

Facts are being gathered:

GATHERING FACTS *************************************************************** 
ok: [foo.us-west-2.compute.internal]
ok: [bar.us-west-2.compute.internal]
ok: [baz.us-west-2.compute.internal]

Let’s see if you have any hostvars … {% for k,v in hostvars.iteritems() %} {{ k }} {{ v }}

Both
u’ansible_hostname’: u’ip-10-72-97-33’
u’ansible_all_ipv4_addresses’: [u’10.72.97.33’]

are present…

But do they have the keys you are looking for?

Absolutely. The keys are present.

I’ve been able to narrow it down to the following:

work:

{% for k,v in hostvars.iteritems() %}
{{ v[‘ansible_all_ipv4_addresses’] }} {{ v[‘ansible_hostname’] }}
{% endfor %}

doesnt:

{% for k,v in hostvars.iteritems() %}
{{ v[‘ansible_all_ipv4_addresses’][0] }} {{ v[‘ansible_hostname’] }}
{% endfor %}

What values do you get in your template for those keys?

Solution:

{% for minion in groups[‘rabbit’] %}
{{ hostvars[minion][‘ansible_all_ipv4_addresses’][0] }} {{ hostvars[minion][‘ansible_hostname’] }}
{% endfor %}

Why didnt this work? :

{% for v in hostvars.iteritems() %}
{{ v[‘ansible_all_ipv4_addresses’][0] }} {{ v[‘ansible_hostname’] }}
{% endfor %}

Thanks Guys!

hostvars.iteritems returns aset of (key,value) so in your case I suspect you are getting a tuple.

{% for (host,facts) in hostvars.iteritems() %}

would be what you would want if doing the above.