# Accessing group vars in templates

**URL:** <https://forum.ansible.com/t/accessing-group-vars-in-templates/12910>\
**Category:** Ansible Project\
**Created:** [June 5, 2013, 4:14pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910 "2013-06-05T16:14:48Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [June 5, 2013, 4:14pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/1 "2013-06-05T16:14:48Z")

</div>

Hello,

Is there any magic variable that can be used inside templates to access  
variables of an arbitrary group (the equivalent of hostvars, but for  
groups) ?

---

<div class="post-metadata">

**Author:** ![Vincent\_Van\_der\_Kuss](https://avatars.discourse-cdn.com/v4/letter/v/7c8e57/32.png) [@Vincent\_Van\_der\_Kuss](https://forum.ansible.com/u/Vincent_Van_der_Kuss)\
**Post date:** [June 5, 2013, 4:58pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/2 "2013-06-05T16:58:46Z")

</div>

Group\_vars?

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 5, 2013, 6:40pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/3 "2013-06-05T18:40:25Z")

</div>

Yeah that doesn’t exist, because you always want to get the variables that have host overrides applied.

You can of course do stuff like:

hostvars[groups[‘webservers’][0]][‘foo’]

---

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [June 5, 2013, 7:19pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/4 "2013-06-05T19:19:49Z")

</div>

Maybe that 'always' is not always 'always'. 😃  
Also, hostvars[groups['webservers'][0]]['foo'] would be different from a  
hypothetical groupvars['webservers']. The first one returns group vars  
overridden with first webserver's vars, while we may want to access the  
'default' webservers group variables. Actually, I think  
'default\_groupvars' would be a better name.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 6, 2013, 12:43pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/5 "2013-06-06T12:43:05Z")

</div>

Can you explain your use case for needing this?

It may help me better understand what a solution may be.

–Michael

---

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [June 6, 2013, 2:40pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/6 "2013-06-06T14:40:09Z")

</div>

Some hosts are managed through a management API, using a common  
management account. The authentication data for that account is stored  
in the group variables of a group consisting of these hosts. Some other  
hosts, which cannot be in a common group with the first group, need to  
do things on the first group, using that management account. The  
solution of having the authentication data in many places is quite  
'dirty'. The solution of having different authentication data for that  
host is also not wanted.

I think that there can be other cases that this might come handy too.  
For example, how can you handle the case in which you want to  
dynamically (e.g. based on some task result or fact) fallback to a  
default group variable and not use the overridden host variable?

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 6, 2013, 2:58pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/7 "2013-06-06T14:58:37Z")

</div>

“For example, how can you handle the case in which you want to  
dynamically (e.g. based on some task result or fact) fallback to a  
default group variable and not use the overridden host variable?”

This sounds like a technical feature rather than a use case. If I may ask, in what situation would you want this?

If you overrode the host variable, you did it because you didn’t want the default.

By the nature of the word “default” it means the value to be used if another preference is not specified. If the default takes priority over  
a host setting it’s no longer a default 🙂

---

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [June 6, 2013, 4:16pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/8 "2013-06-06T16:16:02Z")

</div>

I can think of cases such as falling back to a default continent or country mirroring service in case the local one is down, falling back to using a default storage path in case the more-specific one has not enough space, as well as fallback to a local stand-by backup server in case it is needed to take a snapshot of a great amount of data, but it is not good time to transfer it over the network to a remote site. This is true for the decision flow you have in mind. Another decision flow, however, is falling back to sensible defaults in case the preferred or more specific preselections are not applicable or available. 🙂

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 6, 2013, 6:13pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/9 "2013-06-06T18:13:34Z")

</div>

Ok, so the idea of just taking a value and deciding which to use based on some other criteria is not really a ‘default’ scenario.

Sounds like you want stuff like, vaguely

{% if x \> 5 %}{{ y }}{% else %}{{ z }}{% endif %}

etc

---

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [June 6, 2013, 6:43pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/10 "2013-06-06T18:43:22Z")

</div>

I would write:  
{% if requirements\_are\_met %}{{ host\_specific\_var }}{% else %}{{  
default\_group\_var }}{% endif %}  
or  
{% if host\_resources\_cannot\_be\_used %}{{ default\_group\_var }}{% else  
%}{{ host\_specific\_var }}{% endif %}

Don' t forget that the need is to have vars that are specific to a host  
or host group, but not to write different templates for every possible  
group.

I would also like to see comments on that discussion from other ansible  
users too.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 6, 2013, 9:26pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/11 "2013-06-06T21:26:39Z")

</div>

Ok, so this is already easily done in your case by this:

{% if requirements\_are\_met %}{{ foo\_port }}{% else %}{{  
foo\_port\_if\_requirements\_not\_met }}{% endif %}

Obviously variable names are arbitrary.

Just use different variables for the second.

---

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [June 7, 2013, 7:22am UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/12 "2013-06-07T07:22:28Z")

</div>

Sure, it can be done with different variable names in group variables. But their values are not going to be different from the defaults, since you have cases in which you do want to use the default values instead of the host-specific ones. Having two differently named variables holding the same values is not an elegant solution in my opinion. Also, there is no protection for a specific group variable not to be overridden with a host-specific variable. So, even these duplicate variables can be overridden in a host by mistake and not give a chance to be able to fall back to a group’s default value. Even from a language expressiveness perspective, imho, it can be seen as a limitation of Ansible the fact that it can only express the last computed state of its variables and not the initial state or the intermediate states.

---

<div class="post-metadata">

**Author:** ![Michael\_DeHaan2](https://avatars.discourse-cdn.com/v4/letter/m/da6949/32.png) [@Michael\_DeHaan2](https://forum.ansible.com/u/Michael_DeHaan2)\
**Post date:** [June 7, 2013, 3:25pm UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/13 "2013-06-07T15:25:03Z")

</div>

This conversation strikes me as increasingly theoretical, so I’m not getting it.

Even C can’t express the “previous state of a variable” 🙂

I think we’ll have to agree to disagree about the magnitude of importance of this use case as I’ve offered a few ways to handle your scenario.

I still think you are modelling things a bit strangely to have this requirement.

---

<div class="post-metadata">

**Author:** ![Ernest0x](https://avatars.discourse-cdn.com/v4/letter/e/ed655f/32.png) [@Ernest0x](https://forum.ansible.com/u/Ernest0x)\
**Post date:** [June 8, 2013, 9:45am UTC](https://forum.ansible.com/t/accessing-group-vars-in-templates/12910/14 "2013-06-08T09:45:28Z")

</div>

The solutions that now work involve the overloading of ansible  
inventory, just because there is no direct way to access the group  
variables of an arbitrary group.

For example, how would you avoid the inventory overloading in the  
following model:

There is GroupA with hosts HostA1, HostA2, HostA3 managed through an API  
using a common account. So, the authentication data for this account is  
stored in the group variables of GroupA. When deploying hosts HostA1  
through HostA3, their management account is configured with the  
authentication data that is inherited from GroupA variables.  
Now, you want to configure a management client software in HostB to  
connect to hosts in GroupA through the management API. So, you must  
deploy a configuration file for that client from a template that must  
have access to GroupA variables, because that' s where the  
authentication data is. You could, of course, overload the ansible  
inventory and create a common group with HostB and hosts in GroupA, and  
move authentication data in that group. And you would have to create a  
different common group for every different group of hosts with a common  
management account that HostB needs to access. Also, solutions like  
using hostvars[groups['group\_name'][0]]['somevar'] are neither clean nor  
safe.
