Search code examples
variablesansiblejinja2

Ansible get other group vars


I'm digging into Ansible capabilities a bit further, and I'm looking to implement with a beautiful manner the concept of VIP. To do so, I implemented this variable in the group_vars of my inventory:

group_vars/firstcluster:

vips:
  - name: cluster1_vip
    ip: 1.2.3.4
  - name: cluster1.othervip
    ip: 1.2.3.5

group_vars/secondcluster:

vips:
  - name: cluster2_vip
    ip: 1.2.4.4
  - name: cluster2.othervip
    ip: 1.2.4.5

and in the inventory:

[firstcluster]
node10
node11

[secondcluster]
node20
node21

My question: if I want to set up a DNS server, that gathers all the VIP and associated names (without redundancy for esthetism), how do I proceed? In short: is it possible to get all group variables notwithstanding the hosts underneath?

like:

{% for group in <THEMAGICVAR> %}
{% for vip in group.vips %}
{{ vip.name }}      IN A     {{ vip.ip }}
{% end for %}
{% end for %}

Solution

  • I think you can not access variables of any group directly, but you can access the groups hosts and from the hosts you can access the variables. So looping over all groups and then only picking the first host of each group should do it.

    The magic var you're looking for is groups. Also important is hostvars.

    {%- for group in groups -%}
      {%- for host in groups[group] -%}
        {%- if loop.first -%}
          {%- if "vips" in hostvars[host] -%}
            {%- for vip in hostvars[host].vips %}
    
    {{ vip.name }} IN A {{ vip.ip }}
            {%- endfor -%}
          {%- endif -%}
        {%- endif -%}
      {%- endfor -%}
    {%- endfor -%}
    

    Docs: Magic Variables, and How To Access Information About Other Hosts


    If a host belongs to multiple groups, you might want to filter duplicate entries. In that case you need to collect all values in a dict first and output it in a separate loop like so:

    {% set vips = {} %} {# we store all unique vips in this dict #}
    {%- for group in groups -%}
      {%- for host in groups[group] -%}
        {%- if loop.first -%}
          {%- if "vips" in hostvars[host] -%}
            {%- for vip in hostvars[host].vips -%}
              {%- set _dummy = vips.update({vip.name:vip.ip}) -%} {# we abuse 'set' to actually add new values to the original vips dict. you can not add elements to a dict with jinja - this trick was found at http://stackoverflow.com/a/18048884/2753241#}
            {%- endfor -%}
          {%- endif -%}
        {%- endif -%}
      {%- endfor -%}
    {%- endfor -%}
    
    
    {% for name, ip in vips.iteritems() %}
    {{ name }} IN A {{ ip }}
    {% endfor %}