Categories
DevOps

How to combine group variables with specific names

I have already described how to combine group variables by parsing group configuration files,
so today I will describe how to combine group variables with specific names.

Ansible directory tree used to describe this solution.

$ tree --dirsfirst
.
├── inventory
│   ├── group_vars
│   │   ├── all
│   │   │   └── users.yml
│   │   ├── application
│   │   │   └── users.yml
│   │   ├── backend
│   │   │   └── users.yml
│   │   └── frontend
│   └── hosts.ini
└── users_playbook.yml

Split up group configuration into many small files to apply this solution.

The inventory

Inventory file with overlapping groups.

$ cat inventory/hosts.ini
[application]
beaver
wombat

[frontend]
rabbit

[backend]
beaver
wombat

Group variables defined for every host.

$ cat inventory/group_vars/all/users.yml
---
user__definitions_all:
  - name: milosz
    home: /home/milosz
    shell: /bin/bash
  - name: ansible
    home: /home/ansible
    shell: /bin/bash

Application group variables.

$ cat inventory/group_vars/application/users.yml
---
user__definitions_application:
  - name: django
    home: /home/django
    shell: /bin/bash

Backend group variables.

$ cat inventory/group_vars/backend/users.yml
---
user__definitions_backend:
  - name: milosz
    home: /home/milosz
    shell: /bin/bash
  - name: ansible
    home: /home/ansible
    shell: /bin/bash

Play with users

Create playbook to extract group users.

$ cat users_playbook.yml
---
- hosts: all
  tasks:
    - name: "Display group variables"
      debug:
        msg: "{{ hostvars[inventory_hostname] | select('match', '^user__definitions_[a-z]+$') | list }}"

    - name: "Extract group variables"
      set_fact:
        group_users: >-
          {%- set variables = hostvars[inventory_hostname] | select('match', '^user__definitions_[a-z]+$') | list -%}
          {%- set group_users = [] -%}
          {%- for variable in variables -%}
            {%- set elements = lookup('vars', variable) -%}
            {%- for element in elements -%}
              {%- if element != "" and element not in group_users -%}
                {%- set _ = group_users.extend([element]) -%}
              {%- endif -%}
            {%- endfor -%}  
          {%- endfor -%}
          {{ group_users }}

    - name: "Display group users"
      debug:
        msg: "{{ group_users }}"

Run playbook to inspect group labels.

$ ansible-playbook -i inventory/hosts.ini users_playbook.yml
PLAY [all] *********************************************************************************************************************************************************************
                                            
TASK [Gathering Facts] *********************************************************************************************************************************************************
ok: [beaver]                 
ok: [wombat]                    
ok: [rabbit]
                                            
TASK [Display group variables] *************************************************************************************************************************************************
ok: [beaver] => {
    "msg": [
        "user__definitions_all",
        "user__definitions_application",
        "user__definitions_backend"
    ]                           
}         
ok: [wombat] => {
    "msg": [                        
        "user__definitions_all",
        "user__definitions_application",
        "user__definitions_backend"
    ]
}
ok: [rabbit] => {
    "msg": [                                                                                                                                                                    
        "user__definitions_all"                                                                                                                                                 
    ]                                                                                                                                                                           
}                                                                                                                                                                               

TASK [Extract group variables] *************************************************************************************************************************************************
ok: [beaver]
ok: [wombat]
ok: [rabbit]

TASK [Display group users] *****************************************************************************************************************************************************
ok: [beaver] => {
    "msg": [
        {
            "home": "/home/milosz",
            "name": "milosz",
            "shell": "/bin/bash"
        },
        {
            "home": "/home/ansible",
            "name": "ansible",
            "shell": "/bin/bash"
        },
        {
            "home": "/home/django",
            "name": "django",
            "shell": "/bin/bash"
        }
    ]
}
ok: [wombat] => {
    "msg": [
        {
            "home": "/home/milosz",
            "name": "milosz",
            "shell": "/bin/bash"
        },
        {
            "home": "/home/ansible",
            "name": "ansible",
            "shell": "/bin/bash"
        },
        {
            "home": "/home/django",
            "name": "django",
            "shell": "/bin/bash"
        }
    ]
}
ok: [rabbit] => {
    "msg": [
        {
            "home": "/home/milosz",
            "name": "milosz",
            "shell": "/bin/bash"
        },
        {
            "home": "/home/ansible",
            "name": "ansible",
            "shell": "/bin/bash"
        }
    ]
}

PLAY RECAP *********************************************************************************************************************************************************************
beaver                     : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
rabbit                     : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
wombat                     : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

Additional notes

This is just an example. You can define these variables using group configuration files or roles directly.