'Ansible get all hosts in subgroup

I have the following hosts structure in the inventory:

all:
  children:
    sc:
      hosts:
        sc-finder01a.com:
        sc-finder01b.com:
      vars:
        default_port: 5679
        version: 0.4.2-RELEASE
    ms:
      hosts:
        ms-finder01a.com:
        ms-finder01a.com:
      vars:
        default_port: 5679
        version: 0.4.2-RELEASE

I'm running on all hosts, where for each host I'd like to access the other one in the subgroup (sc/ms) in order to check a condition before executing it on the current host, but I'm struggling to find the syntax. Also, I have to prevent Ansible from executing the command on two hosts in the same subgroup in parallel.

Ideas?



Solution 1:[1]

Have a look at ansible's special variables. For controlling execution, check playbook strategies.

You can access the current host's groups with the group_names variable. If you want to be in control of host execution order, delegate_to and run_once may help, where you assign a run_once controlling server and delegate tasks looping over the group members list.

Solution 2:[2]

Q: "Access the other hosts in the subgroup (sc/ms) in order to check a condition before executing it on the current host."

A: Iterate the list of the hosts in the subgroup(s), e.g.

    - debug:
        msg: "Check a condition on {{ item }}"
      loop: "{{ group_names|map('extract', groups)|flatten|unique|
                difference([inventory_hostname]) }}"

gives

TASK [debug] *******************************************************
ok: [sc-finder01b.com] => (item=sc-finder01a.com) => 
  msg: Check a condition on sc-finder01a.com

ok: [sc-finder01a.com] => (item=sc-finder01b.com) => 
  msg: Check a condition on sc-finder01b.com

ok: [ms-finder01b.com] => (item=ms-finder01a.com) => 
  msg: Check a condition on ms-finder01a.com

ok: [ms-finder01a.com] => (item=ms-finder01b.com) => 
  msg: Check a condition on ms-finder01b.com

Debug

The inventory

shell> cat hosts
all:
  children:
    sc:
      hosts:
        sc-finder01a.com:
        sc-finder01b.com:
      vars:
        default_port: 5679
        version: 0.4.2-RELEASE
    ms:
      hosts:
        ms-finder01a.com:
        ms-finder01b.com:
      vars:
        default_port: 5679
        version: 0.4.2-RELEASE

Display all hosts

    - debug:
        var: groups
      run_once: true

gives

TASK [debug] ***************************************************************
ok: [sc-finder01a.com] => 
  groups:
    all:
    - sc-finder01a.com
    - sc-finder01b.com
    - ms-finder01a.com
    - ms-finder01b.com
    ms:
    - ms-finder01a.com
    - ms-finder01b.com
    sc:
    - sc-finder01a.com
    - sc-finder01b.com
    ungrouped: []

Multiple subgroups

The code works also if a host is a member of multiple subgroups, e.g.

shell> cat hosts
all:
  children:
    sc:
      hosts:
        sc-finder01a.com:
    ms:
      hosts:
        ms-finder01a.com:
    foo:
      hosts:
        foo-bar.com:
        sc-finder01a.com:
        ms-finder01a.com:

gives

TASK [debug] ******************************************************
ok: [sc-finder01a.com] => (item=foo-bar.com) => 
  msg: Check a condition on foo-bar.com
ok: [sc-finder01a.com] => (item=ms-finder01a.com) => 
  msg: Check a condition on ms-finder01a.com

ok: [foo-bar.com] => (item=sc-finder01a.com) => 
  msg: Check a condition on sc-finder01a.com
ok: [ms-finder01a.com] => (item=foo-bar.com) => 
  msg: Check a condition on foo-bar.com

ok: [foo-bar.com] => (item=ms-finder01a.com) => 
  msg: Check a condition on ms-finder01a.com
ok: [ms-finder01a.com] => (item=sc-finder01a.com) => 
  msg: Check a condition on sc-finder01a.com

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 jeroenflvr
Solution 2