12

Here is an example of inventory file:

[web_servers]
web_server-1 ansible_ssh_host=xxx ansible_ssh_user=yyy

[ops_servers]
ops_server-1 ansible_ssh_host=xxx ansible_ssh_user=zzz

Furthermore, web_servers group has specific vars in group_vars/web_servers:

tomcat_jmx_port: 123456

How can I access tomcat_jmx_port var when dealing with ops_servers ?

Some will probably say I need a commun ancessor group (like all) to put common vars, but this is just an example, in true life there are many vars I want to access from ops_servers, and I want to keep things clear so tomcat_jmx_port have to stay in web_servers group_vars file.

In fact, I need a kind of local lookup.

Any idee ?

Thanks for your help.

pierrefevrier
  • 1,570
  • 4
  • 22
  • 33

2 Answers2

14

To access variables from an arbitrary group you'd use the global variable groups which gives you access to all the vars of the hosts in the group. So something like this would return the name of the first host in the web_servers group:

{{ groups['web_servers'][0] }}

To access the individual variables of a host you would do something like this:

{{ hostvars['somehost']['ansible_default_ipv4']['address'] }}

This would return the default IP address of the host named somehost.

You can easily combine hostvars & groups if you need something more complex:

{{ hostvars[groups['web_servers'][0]]['ansible_default_ipv4']['address'] }}

This one will give you the default IP address of the first host in your web_servers group.

Bruce P
  • 19,995
  • 8
  • 63
  • 73
  • Your response is correct, I already knew this solution (`{{ groups['web_servers'][0] }}`) but it looks like a hack :/ Nothing better to simply parse `group_vars` files ? – pierrefevrier Oct 30 '15 at 15:09
  • 1
    No, this is the proper way to access variables. It takes into account [variable precedence](http://goo.gl/rvEBDa), which is something to be aware of. – Bruce P Oct 30 '15 at 15:28
  • Hmm, it doesn't work if you only deploy `ops_servers` (since Ansible do not compute `groupvars` of `web_servers` hosts) – pierrefevrier Dec 04 '15 at 16:34
  • [This question](http://stackoverflow.com/questions/30024664/force-fact-gathering-on-all-hosts) covers what you're running into and how to address it. – Bruce P Dec 04 '15 at 16:43
  • Thanks for the link but I don't like this solution: it could happen long time before deploying again `web_servers`, so `web_servers`'s hosts `facts` could be flushed when I deploy `ops_servers`. You'll be right if you say flush time can be changed but it seems this feature is not designed for long time fact caching. – pierrefevrier Dec 04 '15 at 17:08
9

You can also "include" the variables in the run context using

- include_vars: group_vars/web_servers

Notice that if you have variables with the same name in the context they will be overwritten.

This will make your variable available as {{ tomcat_jmx_port }}

  • Ahaa, that's a pretty cool solution, I did not think about it. It's not perfect because all vars of `web_servers` file will also be included but I prefer this to `{{ groups['web_servers'][0] }}` because there is no need to have a host in the group. Thanks ! – pierrefevrier Nov 03 '15 at 13:26
  • The perfect solution (the one I'm looking for) is the one which allows me to only pick one var value of `web_servers` file – pierrefevrier Nov 03 '15 at 13:32
  • Yeah, the only other way I can think on how approach that is to have nested groups, where you have web_servers and ops_servers part of a bigger group called servers for example and there you placed just the shared properties – Jefferson Girao Nov 03 '15 at 13:46
  • Yep, that's what I do currently. But I think it's not clean since a ops_server don't have to inherit tomcat jmx conf (in the exemple). – pierrefevrier Nov 03 '15 at 13:55