# {"changed": false, "msg": "AnsibleUndefinedVariable:  'ansible.vars.hostvars.HostVarsVars object' has no attribute  'ansible\_default\_ipv4'"}

**URL:** <https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937>\
**Category:** Ansible Project\
**Created:** [November 3, 2018, 8:18pm UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937 "2018-11-03T20:18:12Z")\
**Posts on this page:** 11\
**Page:** 2

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [November 5, 2018, 2:51pm UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/21 "2018-11-05T14:51:51Z")

</div>

It will look up the variable on all host in group mysql

This is the code in the template

&nbsp;&nbsp;{% for host in groups['mysql']%}  
&nbsp;&nbsp;{{hostvars[host]['ansible\_default\_ipv4']['address']}}{% if not loop.last %},{% endif %}  
&nbsp;&nbsp;{% endfor %}

In the inventory he has  
&nbsp;&nbsp;[mysql]  
&nbsp;&nbsp;mysql01  
&nbsp;&nbsp;mysql02  
&nbsp;&nbsp;mysql03  
&nbsp;&nbsp;mysql04

In the first iteration host = mysql01 so he is running  
&nbsp;&nbsp;{{ hostvars['mysql01']['ansible\_default\_ipv4']['address'] }}

But since gather fact has not been run this will get you the error undefined variable.

---

<div class="post-metadata">

**Author:** ![Uwe\_Sauter](https://avatars.discourse-cdn.com/v4/letter/u/41988e/32.png) [@Uwe\_Sauter](https://forum.ansible.com/u/Uwe_Sauter)\
**Post date:** [November 5, 2018, 3:06pm UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/22 "2018-11-05T15:06:19Z")

</div>

As far as I can tell there is no such loop in the template:

[root@awx02 mysql]# cat templates/my.cnf.j2  
[mysqld]  
datadir=/var/lib/mysql  
socket=/var/lib/mysql/mysql.sock  
user=mysql  
binlog\_format=ROW  
bind-address="{{ ansible\_default\_ipv4.address }}"  
default\_storage\_engine=innodb  
innodb\_autoinc\_lock\_mode=2  
innodb\_flush\_log\_at\_trx\_commit=0  
innodb\_buffer\_pool\_size=122M  
wsrep\_provider=/usr/lib64/galera-3/libgalera\_smm.so  
wsrep\_provider\_options="gcache.size=300M; gcache.page\_size=300M"  
wsrep\_cluster\_name="galera\_cluster1"  
wsrep\_cluster\_address="gcomm://{% for host in  
groups['mysql']%}{{hostvars[host]['ansible\_default\_ipv4']['address']}}{%  
if not loop.last %},{% endif %}{% endfor %}"  
wsrep\_sst\_method=rsync  
server\_id=1  
wsrep\_node\_address="{{ ansible\_default\_ipv4.address }}"  
wsrep\_node\_name="{{ ansible\_hostname }}"  
[mysql\_safe]  
log-error=/var/log/mysqld.log  
pid-file=/var/run/mysqld/mysqld.pid

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [November 5, 2018, 3:18pm UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/23 "2018-11-05T15:18:48Z")

</div>

> As far as I can tell there is no such loop in the template:

It is, i just formatted it to show it more clearly.

> [root@awx02 mysql]# cat templates/my.cnf.j2  
> [mysqld]  
> datadir=/var/lib/mysql  
> socket=/var/lib/mysql/mysql.sock  
> user=mysql  
> binlog\_format=ROW  
> bind-address="{{ ansible\_default\_ipv4.address }}"  
> default\_storage\_engine=innodb  
> innodb\_autoinc\_lock\_mode=2  
> innodb\_flush\_log\_at\_trx\_commit=0  
> innodb\_buffer\_pool\_size=122M  
> wsrep\_provider=/usr/lib64/galera-3/libgalera\_smm.so  
> wsrep\_provider\_options="gcache.size=300M; gcache.page\_size=300M"  
> wsrep\_cluster\_name="galera\_cluster1"  
> wsrep\_cluster\_address="gcomm://{% for host in  
> groups['mysql']%}{{hostvars[host]['ansible\_default\_ipv4']['address']}}{%  
> if not loop.last %},{% endif %}{% endfor %}"

The loop is here.

> wsrep\_sst\_method=rsync  
> server\_id=1  
> wsrep\_node\_address="{{ ansible\_default\_ipv4.address }}"  
> wsrep\_node\_name="{{ ansible\_hostname }}"  
> [mysql\_safe]  
> log-error=/var/log/mysqld.log  
> pid-file=/var/run/mysqld/mysqld.pid
> 
> From which message did you get that loop in the template?

See above.

---

<div class="post-metadata">

**Author:** ![Uwe\_Sauter](https://avatars.discourse-cdn.com/v4/letter/u/41988e/32.png) [@Uwe\_Sauter](https://forum.ansible.com/u/Uwe_Sauter)\
**Post date:** [November 5, 2018, 3:23pm UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/24 "2018-11-05T15:23:15Z")

</div>

Ah, I missed that line.

Thanks.

---

<div class="post-metadata">

**Author:** ![user106](https://avatars.discourse-cdn.com/v4/letter/u/41988e/32.png) [@user106](https://forum.ansible.com/u/user106)\
**Post date:** [November 13, 2018, 8:10am UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/25 "2018-11-13T08:10:17Z")

</div>

> > 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:

`[root@awx01 ansible]# rpm -aq|grep -Ei ansible ansible-inventory-grapher-2.4.4-1.el7.noarch ansible-lint-3.4.21-1.el7.noarch ansible-review-0.13.4-1.el7.noarch ansible-doc-2.5.3-1.el7.noarch ansible-2.7.0-1.el7.noarch [root@awx01 ansible]#`

---

<div class="post-metadata">

**Author:** ![user106](https://avatars.discourse-cdn.com/v4/letter/u/41988e/32.png) [@user106](https://forum.ansible.com/u/user106)\
**Post date:** [November 14, 2018, 1:49pm UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/26 "2018-11-14T13:49:16Z")

</div>

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:

`  
[root@awx01 ansible]# vi main.yml

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [November 14, 2018, 2:15pm UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/27 "2018-11-14T14:15:19Z")

</div>

> 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  
> &nbsp;&nbsp;hosts: mysql  
> &nbsp;&nbsp;gather\_facts: true  
> &nbsp;&nbsp;tasks:  
> &nbsp;&nbsp;&nbsp;&nbsp;- debug: msg='{{ inventory\_hostname }} has default IP {{  
> ansible\_default\_ipv4["address"] }}'  
> &nbsp;&nbsp;&nbsp;&nbsp;- template:  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;src: test.j2  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dest: /tmp/test.out  
> &nbsp;&nbsp;tags: mysql
> 
> - name: Install and configure MySQL  
> &nbsp;&nbsp;hosts: mysql  
> &nbsp;&nbsp;become: true  
> &nbsp;&nbsp;roles:  
> &nbsp;&nbsp;&nbsp;&nbsp;- mysql  
> &nbsp;&nbsp;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.

---

<div class="post-metadata">

**Author:** ![Stephen\_C](https://avatars.discourse-cdn.com/v4/letter/s/aca169/32.png) [@Stephen\_C](https://forum.ansible.com/u/Stephen_C)\
**Post date:** [November 16, 2018, 10:53am UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/28 "2018-11-16T10:53:32Z")

</div>

Hi Tom,

Can you try a couple of options and post it to this thread please ?  
With the same inventory file:

`[mysql] mysql01 mysql02 mysql03 mysql04`

`  
ansible-playbook -i infra --limit mysql02 main.yml --tags “mysql” -v

ansible-playbook -i infra --limit mysql03 main.yml --tags “mysql” -v  
`

Thnx,  
Stephen

---

<div class="post-metadata">

**Author:** ![user106](https://avatars.discourse-cdn.com/v4/letter/u/41988e/32.png) [@user106](https://forum.ansible.com/u/user106)\
**Post date:** [November 19, 2018, 6:34am UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/29 "2018-11-19T06:34:17Z")

</div>

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:

`[root@mysql04 ~]# cat /etc/my.cnf [mysqld] datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock user=mysql binlog_format=ROW bind-address="192.168.0.109" default_storage_engine=innodb innodb_autoinc_lock_mode=2 innodb_flush_log_at_trx_commit=0 innodb_buffer_pool_size=122M wsrep_provider=/usr/lib64/galera-3/libgalera_smm.so wsrep_provider_options="gcache.size=300M; gcache.page_size=300M" wsrep_cluster_name="galera_cluster1" wsrep_cluster_address='gcomm://192.168.0.109,192.168.0.102,192.168.0.111' wsrep_sst_method=rsync server_id=1 wsrep_node_address="192.168.0.109" wsrep_node_name="mysql04" [mysql_safe] log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid [root@mysql04 ~]#`

Still, running the limit on any one, as Stephen suggested, fails with the following for any host specified by limit as you mentioned:

`  
ansible-playbook -i infra --limit mysql05 main.yml --tags “mysql” -v --check

fatal: [mysql05]: FAILED! =\> {“changed”: false, “msg”: “AnsibleUndefinedVariable: ‘ansible.vars.hostvars.HostVarsVars object’ has no attribute ‘ansible\_default\_ipv4’”}  
`

`  
ansible-playbook -i infra --limit mysql06 main.yml --tags “mysql” -v --check

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.

Cheers,  
Tom

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [November 19, 2018, 2:24pm UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/30 "2018-11-19T14:24:03Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![user106](https://avatars.discourse-cdn.com/v4/letter/u/41988e/32.png) [@user106](https://forum.ansible.com/u/user106)\
**Post date:** [November 20, 2018, 1:24am UTC](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937/31 "2018-11-20T01:24:57Z")

</div>

Kool. So it’s really saying (bolded):

ansible-playbook -i infra --limit mysql06 main.yml --tags “mysql” -v --check

fatal: [mysql06]: FAILED! =\> {“changed”: false, “msg”: “AnsibleUndefinedVariable: ‘ansible.vars.hostvars.HostVarsVars object’ has no attribute ‘ansible\_default\_ipv4’ **for mysql05.** ”}

Makes sense. Ty.

Cheers,  
TK

[Previous page](https://forum.ansible.com/t/changed-false-msg-ansibleundefinedvariable-ansible-vars-hostvars-hostvarsvars-object-has-no-attribute-ansible-default-ipv4/28937.md?page=1)
