# using hostvars not resolving variables "calculated" from facts

**URL:** <https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847>\
**Category:** Ansible Project\
**Created:** [March 25, 2014, 2:58am UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847 "2014-03-25T02:58:50Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![Matt\_Coddington](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Matt\_Coddington](https://forum.ansible.com/u/Matt_Coddington)\
**Post date:** [March 25, 2014, 2:58am UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847/1 "2014-03-25T02:58:50Z")

</div>

Using Ansible 1.5.3

I’m having some trouble with a situation where I have a variable that I’d like to use in a template that uses “hostvars” but the variable in question is calculated from facts.

I have a template that looks like this:

{% for host in groups[‘uat4-webapp’]|sort %}

BalancerMember ajp://{{ hostvars[host].webapp\_ip }}:8009 loadfactor=20

{% endfor %}

The “webapp\_ip” variable is calculated like this in a group\_vars file:

webapp\_ip: “{{ ansible\_eth0.ipv4.address }}”

When I compile the template above, it ends up looking like this:

BalancerMember ajp://{{ ansible\_eth0.ipv4.address }}:8009 loadfactor=20

When I expected it to look like this:

BalancerMember ajp://[10.10.1.36:8009](http://10.10.1.36:8009) loadfactor=20

The reason for this “webapp\_ip” variable as opposed to using the facts directly is because I need it set to different things in different places (one group of hosts has it at ansible\_eth0.ipv4.address, another at ansible\_bond0.ipv4.address, etc).

Is this something that should work, or should I be looking to accomplish this a different way?

thanks!  
matt

---

<div class="post-metadata">

**Author:** ![C\_Morgan\_Hamill](https://avatars.discourse-cdn.com/v4/letter/c/ebca7d/32.png) [@C\_Morgan\_Hamill](https://forum.ansible.com/u/C_Morgan_Hamill)\
**Post date:** [March 25, 2014, 12:39pm UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847/2 "2014-03-25T12:39:07Z")

</div>

Excerpts from Matt Coddington's message of 2014-03-24 22:58:50 -0400:

> Using Ansible 1.5.3
> 
> I'm having some trouble with a situation where I have a variable that I'd  
> like to use in a template that uses "hostvars" but the variable in question  
> is calculated from facts.
> 
> I have a template that looks like this:
> 
> {% for host in groups['uat4-webapp']|sort %}  
> BalancerMember ajp://{{ hostvars[host].webapp\_ip }}:8009 loadfactor=20  
> {% endfor %}
> 
> The "webapp\_ip" variable is calculated like this in a group\_vars file:
> 
> webapp\_ip: "{{ ansible\_eth0.ipv4.address }}"

> Is this something that should work, or should I be looking to accomplish  
> this a different way?

Ansible seems to evaluate somewhat lazily, so "{{ansible\_eth0.ipv4.address}}"  
get evaluated in the context of the current host.

You'll probably need to be explicit:

&nbsp;&nbsp;&nbsp;&nbsp;{{ hostvars[host].ansible\_eth0.ipv4.address }}

---

<div class="post-metadata">

**Author:** ![Matt\_Coddington](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Matt\_Coddington](https://forum.ansible.com/u/Matt_Coddington)\
**Post date:** [March 25, 2014, 6:15pm UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847/3 "2014-03-25T18:15:18Z")

</div>

Thanks Morgan,  
That's what i was afraid of... you're correct that explicitly referencing  
those does work, and I can do this in the template by having different  
cases for the different sets of servers (e.g. "if prod, use  
ansible\_bond0.ipv4.address, if staging use ansible\_eth0.ipv4.address,  
etc"). I was just hoping there was a way to abstract that if/then logic  
into a common variable outside the template.

thanks,  
matt

---

<div class="post-metadata">

**Author:** ![C\_Morgan\_Hamill](https://avatars.discourse-cdn.com/v4/letter/c/ebca7d/32.png) [@C\_Morgan\_Hamill](https://forum.ansible.com/u/C_Morgan_Hamill)\
**Post date:** [March 25, 2014, 6:27pm UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847/4 "2014-03-25T18:27:09Z")

</div>

Excerpts from Matt Coddington's message of 2014-03-25 14:15:18 -0400:

> \> \> {% for host in groups['uat4-webapp']|sort %}  
> \> \> BalancerMember ajp://{{ hostvars[host].webapp\_ip }}:8009 loadfactor=20  
> \> \> {% endfor %}  
> \> \>  
> \> \> The "webapp\_ip" variable is calculated like this in a group\_vars file:  
> \> \>  
> \> \> webapp\_ip: "{{ ansible\_eth0.ipv4.address }}"  
> \> {{ hostvars[host].ansible\_eth0.ipv4.address }}  
> That's what i was afraid of... you're correct that explicitly referencing  
> those does work, and I can do this in the template by having different  
> cases for the different sets of servers (e.g. "if prod, use  
> ansible\_bond0.ipv4.address, if staging use ansible\_eth0.ipv4.address,  
> etc"). I was just hoping there was a way to abstract that if/then logic  
> into a common variable outside the template.

Idea, untested:

In your template:

&nbsp;&nbsp;&nbsp;&nbsp;{% for host in groups['uat-webapp']|sort %}  
&nbsp;&nbsp;&nbsp;&nbsp;BalancerMember ajp://{{ hostvars[host][hostvars[host][webapp\_iface]].ipv4.address }}  
&nbsp;&nbsp;&nbsp;&nbsp;{% endfor %}

In your group\_vars file:

&nbsp;&nbsp;&nbsp;&nbsp;webapp\_iface: "ansible\_bond0"

Or what have you.

Or this might work:

Leave your template as is, and try putting in your group\_vars file:

&nbsp;&nbsp;&nbsp;&nbsp;webapp\_ip: "{{ hostvars[inventory\_hostname].ansible\_eth0.ipv4.address }}"

Also, you might want to look into setting your own facts, as those are  
per-host.

---

<div class="post-metadata">

**Author:** ![Matt\_Coddington](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Matt\_Coddington](https://forum.ansible.com/u/Matt_Coddington)\
**Post date:** [March 25, 2014, 6:56pm UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847/5 "2014-03-25T18:56:46Z")

</div>

Hey Morgan,  
Thanks so much for this… all very good ideas, I see how they may work outside of the current way I was thinking about this problem… will definitely try a few out and let the list know where I land 🙂

matt

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [March 25, 2014, 6:58pm UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847/6 "2014-03-25T18:58:53Z")

</div>

I would not expect you would need to do this above workaround if the current variable had an eth0 address.

If you are in fact seeing that, please file a ticket and we can take a look.

---

<div class="post-metadata">

**Author:** ![Matt\_Coddington](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Matt\_Coddington](https://forum.ansible.com/u/Matt_Coddington)\
**Post date:** [March 25, 2014, 7:04pm UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847/7 "2014-03-25T19:04:37Z")

</div>

> I would not expect you would need to do this above workaround if the  
> current variable had an eth0 address.

Thanks Michael... I don't understand what "the current variable having an  
eth0 address" means... you mean the current host i'm referring to in  
hostvars? it definitely has an eth0 address and if that should in fact  
work i can submit a ticket with a pretty minimal setup to reproduce i think.

thanks,  
matt

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [March 25, 2014, 7:07pm UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847/8 "2014-03-25T19:07:37Z")

</div>

I mean if it’s the current host in the host loop, for which you are writing the template.

(You shouldn’t have to indirect through the hostvars structure unless you need the variables for another host).

---

<div class="post-metadata">

**Author:** ![Matt\_Coddington](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Matt\_Coddington](https://forum.ansible.com/u/Matt_Coddington)\
**Post date:** [March 25, 2014, 7:16pm UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847/9 "2014-03-25T19:16:43Z")

</div>

gotcha, yeah i need the variables from another host so sounds like the indirect method is the way to go.

thanks!  
matt

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan1](https://avatars.discourse-cdn.com/v4/letter/m/5e9695/32.png) [@Michael\_DeHaan1](https://forum.ansible.com/u/Michael_DeHaan1)\
**Post date:** [March 25, 2014, 7:18pm UTC](https://forum.ansible.com/t/using-hostvars-not-resolving-variables-calculated-from-facts/14847/10 "2014-03-25T19:18:22Z")

</div>

Right, looking back at the first post, I wouldn’t expect webapp\_ip to be something in hostvars like that.

BalancerMember ajp://{{ hostvars[host][hostvars[host][webapp\_iface]].ipv4.address }}

is the way to go

It can be shortened with a “set statement” in Jinja2 if you want, though, if you plan to reuse it throughout the file
