I have a jinja2 template, and I'm trying to loop through a host group, and insert the ipv4 address of all the hosts in my template. But I'm getting an error when I do it, even though the way I'm doing it is the way every post and article suggest it should be done.
Here's the template that's producing the error:
{% if groups['linux-hosts'] %}
{% for item in groups['linux-hosts'] %}
define host {
use generic-host-normal
host_name {{ item }}
alias {{ item }}
address {{ hostvars[item].ansible_default_ipv4.address }}
}
{% endfor %}
{% endif %}
And the error I'm getting is:
failed: [server] (item=servers.cfg) => {"changed": false, "item": "servers.cfg", "msg": "AnsibleUndefinedVariable: 'ansible.vars.hostvars.HostVarsVars object' has no attribute 'ansible_default_ipv4'"}
If I don't use the variable 'item' in the square brackets, but instead specify a specific host from the inventory, Ansible is able to get the ipv4 address. Example ('server' is the name of a host from my inventory):
{{ hostvars['server'].ansible_default_ipv4.address }}
I came across this problem with a similar use case. My problem turned out to be that I included hosts in a group which were not the target of the play. Therefore gather facts had not run against all the hosts in the group. I fixed this by running setup against all the hosts I needed like this
- name: get cluster facts
hosts: k8s-cluster
tags:
- always
tasks:
- name:
setup:
become: true
- name: deploy HA Proxy
hosts: kube-master
become: yes
roles:
- { role: ansible-role-haproxy }
Note: kube-master is a subset of k8s-cluster