Sure, but the template will only be used for the one host and as such should not look for variables of other hosts, right?
It will look up the variable on all host in group mysql
This is the code in the template
{% for host in groups[‘mysql’]%}
{{hostvars[host][‘ansible_default_ipv4’][‘address’]}}{% if not loop.last %},{% endif %}
{% endfor %}
In the inventory he has
[mysql]
mysql01
mysql02
mysql03
mysql04
In the first iteration host = mysql01 so he is running
{{ hostvars[‘mysql01’][‘ansible_default_ipv4’][‘address’] }}
But since gather fact has not been run this will get you the error undefined variable.
Sorry for the late reply. We might have lost track of the original error. mysql0[1-3] are ok and print all variables. Only host mysql04 prints the undefined variable. (see above). Going to do more tests on your suggestions and see further. Included a few of the modifications Uwe pointed out as well. My Ansible version:
Ok. So I removed a couple of tags from the mysql task "mysql : Copy my.cnf
global MySQL configuration." and adjusted the play as follows:
The playbook is fine, the problem is the limit option your are using on ansible-playbook.
[root@awx01 ansible]# vi main.yml
---
- name: Gather all facts prior to execution
hosts: mysql
gather_facts: true
tasks:
- debug: msg='{{ inventory_hostname }} has default IP {{
ansible_default_ipv4["address"] }}'
- template:
src: test.j2
dest: /tmp/test.out
tags: mysql
- name: Install and configure MySQL
hosts: mysql
become: true
roles:
- mysql
tags: mysql
But that didn't work. Still got the original error with mysql04. Until I
removed mysql01-3 from the infra file leaving only mysql04:
[mysql]
mysql04
And reran using:
ansible-playbook -i infra --limit mysql04 main.yml --tags "mysql" -v
You still have the same problem I commented on earlier.
When you run a with --limit, the task and *gather_facts* is only run on host specified in the limit.
So when you in you template try using facts for mysql01-03 they don't exist since you haven't gather them so you get the error message.
So remove you --limit and it will work, the template you have will never work if you specify limit.
So I’ve made two more empty hosts and called them mysql05 and mysql06 and tested on all 3 (this way I don’t blow away my working cluster). Now I removed the limit flag and run it like this:
`
ansible-playbook -i infra main.yml --tags “mysql” -v
`
Everything worked well and the /etc/my.cnf was populated as expected:
fatal: [mysql06]: FAILED! => {“changed”: false, “msg”: “AnsibleUndefinedVariable: ‘ansible.vars.hostvars.HostVarsVars object’ has no attribute ‘ansible_default_ipv4’”}
`
But it seems to work opposite to the way described above (Apologies if I’m misreading). The error is thrown for ANY host that I use the –limit flag on, not the ones that I don’t use the limit on.
I would have expected it to gather facts on the host I’m limiting the run too, not the ones I’m excluding.
Yes, it's only gathering facts on the host in the limit.
The error message isn't about that it can't find ansible_default_ipv4 on the host in the limit (mysql06), it's about mysql06 cant find ansible_default_ipv4 for host mysql05.