Mickael Bertainchant
Mickael Bertainchant

Reputation: 42

Why, in Ansible, I can't have same key in many children groups?

I want to make some clean stuff with my ansible hosts file.

If i use ansible-playbook --limit calendar -i hosts update_common.yml

Ansible execute my playbook on all hosts, even on hostname in other groups.

Apparently, it seems to comme from my keys dev and prod :

all:
  children:
    gitlab:
      children:
        dev:
          hosts:
            gitlab-dev:  # Stretch
        prod:
          hosts:
            gitlab-A:   # Stretch
            gitlab-B:   # Stretch
            gitlab-C.mysociety.fr:
              ansible_port: 22
    intranet:
      children:
        dev:
          hosts:
            intra-dev:      # Buster
            wordpress-dev:  # Buster
        prod:
          hosts:
            intra-prod:     # Buster
    calendar:
      children:
        dev:
          hosts:
            calendar-dev:
        prod:
          hosts:
            calendar:

Upvotes: 1

Views: 2597

Answers (6)

mgosk
mgosk

Reputation: 1874

You can't have same childeren key in tree, but probably you can resign from tree struct and just assign your hosts to multiple independendent groups.

all:
  children:
    gitlab:
      hosts:
        gitlab-dev:
        gitlab-prod:
    calendar:
      hosts:
        calendar-dev:
        calendar-prod:
    dev:
      hosts:
        gitlab-dev:
        calendar-dev:
    prod:
      hosts:
        gitlab-prod:
        calendar-prod:  

Upvotes: 0

energenious
energenious

Reputation: 59

do you of any workaround to share the same group variables for all new unique host names, such that:

the variable file group_vars/de.yml

is shared among all hosts in this example?

gitlab:
  gitlab_dev:
intranet:
  intranet_dev:

Upvotes: 0

queeg
queeg

Reputation: 9372

I believe Ansible interprets the inventory slightly different.

You specify the playbook to be executed on all hosts in the calendar group. That one contains everything in the children group. And since children also contains gitlab and intranet...

Very likely the problem is that you use the keyword at many different levels and locations. If that should work, you'd have to specify a path for the playbook run. Seems just not the way Ansible was designed.

Upvotes: 1

Mickael Bertainchant
Mickael Bertainchant

Reputation: 42

Yes when I make ansible-inventory -i hosts --list

We can see how it is managed, dev hosts are grouped together, same for prod :(

    "all": {
        "children": [
            "calendar", 
            "gitlab", 
            "intranet", 
            "ungrouped"
        ]
    }, 
    "dev": {
        "hosts": [
            "calendar-dev", 
            "gitlab-test", 
            "intra-dev", 
            "wordpress-dev"
        ]
    }, 
    "fil-calendar": {
        "children": [
            "dev", 
            "prod"
        ]
    }, 
    "gitlab": {
        "children": [
            "dev", 
            "prod"
        ]
    }, 
    "intranet": {
        "children": [
            "dev", 
            "prod"
        ]
    }, 
    "prod": {
        "hosts": [
            "calendar", 
            "gitlab-A", 
            "gitlab-B", 
            "gitlab-C.mysociety.fr", 
            "intra-prod"
        ]
    }

Upvotes: 0

Vladimir Botka
Vladimir Botka

Reputation: 67959

Ansible doesn't store the group's tree. The structure is a flat list of all groups. Each group comprises a cumulative list of hosts. If you run the play below

- hosts: all
  tasks:
    - debug:
        msg: "{{ groups[item] }}"
      loop: "{{ groups.keys()|list }}"
      run_once: true

you'll see that the groups gitlab, intranet, and calendar are identical because they comprise all the hosts from the groups dev and prod. Next, you'll see that the group dev comprises all four hosts, and the group prod comprises all five hosts.

See Ansible: Intersection of two host groups using yaml inventory.


Flatten the structure to achieve what you want, e.g.

all:
  children:
    gitlab_dev:
      hosts:
        gitlab-dev:  # Stretch
    gitlab_prod:
      hosts:
        gitlab-A:   # Stretch
        gitlab-B:   # Stretch
        gitlab-C.mysociety.fr:
          ansible_port: 22
    intranet_dev:
      hosts:
        intra-dev:      # Buster
        wordpress-dev:  # Buster
    intranet_prod:
      hosts:
        intra-prod:     # Buster
    calendar_dev:
      hosts:
        calendar-dev:
    calendar_prod:
      hosts:
        calendar:

Upvotes: 4

Andrew
Andrew

Reputation: 4612

Group names must be unique, it's just the way ansible works. You can either create separate inventory files with same group names, and invoke your playbooks with different inventories or have unique group names.

See this issue https://github.com/ansible/ansible/issues/32247 and comment from one of the devs:

This won't work as group names are unique, they are not based on their relationships with other groups.

I recommend creating parent1_subgroup1 named groups that have the hierarchy you want built in.

Upvotes: 3

Related Questions