4

I have the following groups defined in my inventory:

[webservers]

[server_storage]

[server_ws1]

[webservers:children]
server_storage
server_ws1

During my play, I'm in need of getting the names of the children groups of group['webservers'] ONLY (I think of theese as 'subgroups')

So, let's say I would need to set_fact a variable that contains in this case, the list of strings:

 - server_storage
 - server_ws1

This would have to be dynamic, so if I add group 'server_ws2' to group['webservers'], this should return

 - server_storage
 - server_ws1
 - server_ws2

I've been playing with the use of group_names, group['webservers'] (which doesn't return subgroups, but hostnames)

Basically, I need a simple way of getting a the list of subgroups of a specific group. Is this possible without the use of black magic?

UPDATE: The idea, is that the hosts could belong to more groups, but I need only the subgroups or children of webservers group. It's constant, no matter the host, the output should allways be the same.

By the way, this one didn't work How can I get a list of child groups in Ansible?, because it retuns all groups for the current host, I need only subgroups of the specified group.

ndelucca
  • 517
  • 1
  • 8
  • 20

1 Answers1

1

Q: "Get the names of the children groups of group['webservers']"

A: For example, the inventory

shell> cat hosts
[webservers]

[server_storage]
host_01

[server_ws1]
host_02

[webservers:children]
server_storage
server_ws1

and the playbook

shell> cat playbook.yml
- hosts: webservers
  tasks:

    - set_fact:
        subgroups: "{{ subgroups|default([]) + hostvars[item].group_names }}"
      loop: "{{ groups.webservers }}"
      run_once: true

    - debug:
        msg: "{{ subgroups|unique|difference(['webservers']) }}"
      run_once: true

give (abridged)

shell> ansible-playbook -i hosts playbook.yml 

  msg:
  - server_storage
  - server_ws1

As a workaround, it's possible to use ansible-inventory to list the structure of the inventory, store the output in a file, and use this file as needed, e.g. include_vars in a playbook. See the example below

shell> cat hosts
host_01
host_02

[webservers]

[server_storage]

[server_ws1]

[webservers:children]
server_storage
server_ws1
shell> ansible-inventory -i hosts --list --output hosts.json
shell> cat hosts.json
{
    "_meta": {
        "hostvars": {}
    },
    "all": {
        "children": [
            "ungrouped",
            "webservers"
        ]
    },
    "ungrouped": {
        "hosts": [
            "host_01",
            "host_02"
        ]
    },
    "webservers": {
        "children": [
            "server_storage",
            "server_ws1"
        ]
    }
Vladimir Botka
  • 58,131
  • 4
  • 32
  • 63
  • I appreciate the answer, but it does not work as intended. I'll update de question with the problem. Your answer works only if those hosts belong only to those groups, but if they belong to additional groups, those show up as well with your code. – ndelucca Jul 30 '20 at 13:58
  • Ansible does not collect any information about the group's structure. Only `hostvars[item].group_names` is available. As a result: 1) It's not possible to analyze the structure of empty groups from a playbook. 2) It's possible to intersect/difference flat lists of the groups only. – Vladimir Botka Jul 30 '20 at 14:21
  • I understand, seems like there's no simple way of achieving what I need, (the reason of actually needing this is a long story, it's not a whim, so far couldn't find a way to re-structure some things on my current setup to make this become unnecesary). I had a feeling this was going to be the case, hence the "black magic" comment. Thank you for the effort though. I'll keep this open for a while and see If someone comes up with a workaround, and if nothing happens, mark your answer as the correct one. Thanks. – ndelucca Jul 30 '20 at 14:32
  • As a workaround, try `ansible-inventory`. I've updated the answer with an example. – Vladimir Botka Jul 30 '20 at 14:49