This is a text-only version of the following page on https://raymii.org: --- Title : Ansible: access group vars for groups the current host is not a member of Author : Remy van Elst Date : 27-01-2017 URL : https://raymii.org/s/tutorials/Ansible_access_other_groups_group_vars.html Format : Markdown/HTML --- ![ansible logo][1] This guide shows you how to access group variables for a group the current host is not a member of. In Ansible you can access other host variables using `hostvars['hostname']` but not group variables. The way described here is workable, but do I consider it a dirty hack. So why did I need this? I have a setup where ssl is offloaded by haproxy servers, but the virtual hosts and ssl configuration are defined in Apache servers. The loadbalancers and appservers are two different hostgroups, the ssl settings are in the appserver group_vars, which the hosts in the loadbalancer group need to access. The best way to do this is change the haproxy playbooks and configuration and define the certificates there, but in this specific case that wasn't a workable solution. Editing two yaml files (one for the appservers and one for the loadbalancers) was not an option in this situation. <p class="ad"> <b>Recently I removed all Google Ads from this site due to their invasive tracking, as well as Google Analytics. Please, if you found this content useful, consider a small donation using any of the options below:</b><br><br> <a href="https://leafnode.nl">I'm developing an open source monitoring app called Leaf Node Monitoring, for windows, linux & android. Go check it out!</a><br><br> <a href="https://github.com/sponsors/RaymiiOrg/">Consider sponsoring me on Github. It means the world to me if you show your appreciation and you'll help pay the server costs.</a><br><br> <a href="https://www.digitalocean.com/?refcode=7435ae6b8212">You can also sponsor me by getting a Digital Ocean VPS. With this referral link you'll get $100 credit for 60 days. </a><br><br> </p> This is applicable for other scenario's as well. In templates this can be worked around by looping over all the groups, then over all the hosts in the specific group, then if the host is the first in the loop, go over all the hostvars for that host and then access the group var you want. [This stackoverflow][3] post goes over that. In my case I needed to access it in a playbook, the looping construction woudln't work there. ### The inventory In the inventory file I created a new group. This group has the two other groups, `appservers` and `loadbalancers` in them and nothing else. Like so: [appserver] app1.cluster app2.cluster [loadbalancer] lb1.cluster lb2.cluster [ssl:children] loadbalancer appserver The shortnames expand to specifc SSH configuration. The `ssl` hostgroup effectively includes the following hosts: * app1 * app2 * lb1 * lb2 However, we do need to modify the playbook that modifies the vhosts to only place the certificates on the loadbalancers, and do nothing with the certificates on the appservers. The playbook should still do it's normal thing, configuring the vhosts, on the appservers, but not on the loadbalancers. [The documentation][4] has more information on hostgroups based on other groups. ### The playbook The playbook (`deploy-vhosts.yml`) first was this: --- - hosts: appserver roles: - apache-vhost After changing the hostgroup we need to add the specific role that deploys the certificates. We also put a `when` in place to make sure the two roles only run on the hosts where they should and not the other hosts: --- - hosts: ssl roles: - {role: apache-vhost, when: "'appserver' in group_names" } - {role: sslcerts, when: "'loadbalancer' in group_names " } ### The group vars The group vars for the appservers contain the following information to configure the virtual hosts: --- apache_vhost: example.cluster.nl: name: example.cluster.nl docroot: /home/example-cluster/domains/example.cluster.nl/public-html/ webuser: example-cluster ssl_name: example.cluster.nl serveraliases: - www.example.cluster.nl example2.cluster.nl: name: example2.cluster.nl docroot: /home/example2-cluster/domains/example2.cluster.nl/public-html/ webuser: example2-cluster ssl_name: example2.cluster.nl serveraliases: - www.example2.cluster.nl The problem is that, when the deploy vhosts playbook in run on the loadbalancers, they cannot access these variables since they are not in the same group. ### The role The role `sslcerts` has one task file and one handler (`restart haproxy`). It makes sure the folder for the certificates exists and it places the certificate files there. There are extra when statements to make sure it only runs on the loadbalancers. - name: create ssl folder file: path: /etc/ssl/cluster/ state: directory owner: root group: root when: "'loadbalancer' in group_names" tags: ssl - name: place certificates copy: src: files/ssl/{{ item.value.ssl_name }}.pem dest: /etc/ssl/cluster/{{ item.value.ssl_name }}.pem with_dict: '{{ apache_vhost }}' when: "'loadbalancer' in group_names" notify: restart haproxy tags: ssl ### The crux Even after configuring the special playbook that runs on all the hosts, the loadbalancers still cannot access the group variables from the appservers. The dirty hack part is that we symlink the group vars from the `appserver` folder to the `loadbalancer` folder: ln -s /home/deploy/ansible/group_vars/appserver/apache-vhost.yml /home/deploy/ansible/group_vars/loadbalancer/apache-vhost-symlink.yml Now, the loadbalancers have the group variable `apache_vhost` as well, and when the file in the `appserver` folder is changed, the `loadbalancer` file is as well because it's a symlink. ### haproxy haproxy in this case has one frontend where all traffic comes into, the appservers handle the different virtual hosts: frontend https-in mode http bind 1.2.3.4:443 ssl crt /etc/ssl/cluster/ no-sslv3 acl secure dst_port eq 443 rsprep ^Set-Cookie:\ (.*) Set-Cookie:\ \1;\ Secure if secure rspadd Strict-Transport-Security:\ max-age=31536000 if secure option httplog option forwardfor option http-server-close option httpclose reqadd X-Forwarded-Proto:\ https default_backend appserver haproxy handles `sni` transparantly based on the requested hostname, if it finds the certificate in the folder `/etc/ssl/cluster/`. The files there are a concatenation of the public key, the private key and if needed the certificate chain. ### Conclusion In this case it might be better to change the haproxy playbook to handle this, or to change the group_vars to `all`. However, this environment has certain constraints set, so this 'suboptimal' workaround works. [1]: https://raymii.org/s/inc/img/ansible-logo.png [2]: https://www.digitalocean.com/?refcode=7435ae6b8212 [3]: https://stackoverflow.com/questions/34614337/ansible-get-other-group-vars [4]: https://docs.ansible.com/ansible/intro_inventory.html#groups-of-groups-and-group-variables --- License: All the text on this website is free as in freedom unless stated otherwise. This means you can use it in any way you want, you can copy it, change it the way you like and republish it, as long as you release the (modified) content under the same license to give others the same freedoms you've got and place my name and a link to this site with the article as source. This site uses Google Analytics for statistics and Google Adwords for advertisements. You are tracked and Google knows everything about you. Use an adblocker like ublock-origin if you don't want it. All the code on this website is licensed under the GNU GPL v3 license unless already licensed under a license which does not allows this form of licensing or if another license is stated on that page / in that software: This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. Just to be clear, the information on this website is for meant for educational purposes and you use it at your own risk. I do not take responsibility if you screw something up. Use common sense, do not 'rm -rf /' as root for example. If you have any questions then do not hesitate to contact me. See https://raymii.org/s/static/About.html for details.