рüффп
рüффп

Reputation: 5448

Groups in my Ansible inventory does not work as expected

My yaml inventory (dev environment) is like this:

$> more inventory/dev/hosts.yml 

all:
  children:
    dmz1:
      children:
        ch:
          children:
            amq:
              hosts:
                myamqdev01.company.net: nodeId=1
                myamqdev02.company.net: nodeId=2
            smx:
              hosts:
                mysmxdev01.company.net: nodeId=1
                mysmxdev02.company.net: nodeId=2
    intranet:
      children:
        ch:
          children:
            amq:
              hosts:
                amqintradev01.company.net: nodeId=1
                amqintradev02.company.net: nodeId=2
            smx:
              hosts:
                smxintradev01.company.net: nodeId=1
                smxintradev02.company.net: nodeId=2  

and when I try to ping (with ansible -i inventory/dev -m ping all I got the error:

children: | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname children:: Temporary failure in name resolution", 
    "unreachable": true
}
ch: | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname ch:: Temporary failure in name resolution", 
    "unreachable": true
}
all: | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname all:: Temporary failure in name resolution", 
    "unreachable": true
}
lan: | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname lan:: Temporary failure in name resolution", 
    "unreachable": true
}
amq: | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname amq:: Temporary failure in name resolution", 
    "unreachable": true
}
hosts: | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname hosts:: Temporary failure in name resolution", 
    "unreachable": true
}

etc...

For troubleshooting, when I execute ansible -i inventory/dev --list-hosts all I got:

hosts (16):
  all:
  children:
  dmz1:
  ch:
  amq:
  hosts:
  myamqdev01.company.net:
  myamqdev02.company.net:
  smx:
  mysmxdev01.company.net:
  mysmxdev02.company.net:
  intranet:
  amqintradev01.company.net:
  amqintradev02.company.net:
  smxintradev01.company.net:
  smxintradev02.company.net:

I think this command should only give the hosts, no?

I am not sure what is the issue but I followed the example from the official doc and I think there's a problem with my hosts.yml file but cannot guess what I am missing.

UPDATE When I correct the nodeId variables according to the answer, the list all is working fine. However when I try to filter by an intermediate parent this is not working:

ansible -i inventory/dev --list-hosts intranet

does not return the intranet hosts but all.

When I try: ansible -i inventory/dev --list-hosts amq only amq server are properly returned.

Upvotes: 1

Views: 1978

Answers (1)

Zeitounator
Zeitounator

Reputation: 44615

Your inventory file does not respect ansible's format so the yaml inventory plugin fails to parse it. Since it tries plugins in order, for some reason I don't really get it finally succeeds using the ini format and gives one host for each line in your file.

Moreover, you have to understand that a group (e.g. smx) contains all the hosts that have been defined in the inventory, wherever they have been defined (e.g. as a children of intranet or dmz1).

So in your actual inventory structure, dmz1 and intranet both contain as children the groups amq and smx which themselves contain all hosts defined, either in the intranet or dmz1 section. Hence the groups all, dmz1 and intranet are all equivalent here and contain all hosts in the inventory.

Here is an inventory fixing your format problems and with a slightly different structure to address your expectation in terms of group targeting:

---
all:
  children:
    dmz1:
      hosts:
        myamqdev01.company.net:
          nodeId: 1
        myamqdev02.company.net:
          nodeId: 2
        mysmxdev01.company.net:
          nodeId: 1
        mysmxdev02.company.net:
          nodeId: 2
    intranet:
      hosts:
        amqintradev01.company.net:
          nodeId: 1
        amqintradev02.company.net:
          nodeId: 2
        smxintradev01.company.net:
          nodeId: 1
        smxintradev02.company.net:
          nodeId: 2
    amq:
      hosts:
        myamqdev01.company.net:
        myamqdev02.company.net:
        amqintradev01.company.net:
        amqintradev02.company.net:
    smx:
      hosts:
        mysmxdev01.company.net:
        mysmxdev02.company.net:
        smxintradev01.company.net:
        smxintradev02.company.net:

And here are a few example of how to target the desired groups of machines

$ # All machines
$ ansible -i dev/ --list-hosts all
  hosts (8):
    myamqdev01.company.net
    myamqdev02.company.net
    mysmxdev01.company.net
    mysmxdev02.company.net
    amqintradev01.company.net
    amqintradev02.company.net
    smxintradev01.company.net
    smxintradev02.company.net
$ # Intranet
$ ansible -i dev/ --list-hosts intranet
  hosts (4):
    amqintradev01.company.net
    amqintradev02.company.net
    smxintradev01.company.net
    smxintradev02.company.net
$ # all smx machines
$ ansible -i dev/ --list-hosts smx
  hosts (4):
    mysmxdev01.company.net
    mysmxdev02.company.net
    smxintradev01.company.net
    smxintradev02.company.net
$ # amq machines only on dmz1
$ # 1. Only whith patterns
$ ansible -i dev/ --list-hosts 'amq:&dmz1'
  hosts (2):
    myamqdev01.company.net
    myamqdev02.company.net
$ # 2. Using limit
$ ansible -i dev/ --list-hosts amq -l dmz1
  hosts (2):
    myamqdev01.company.net
    myamqdev02.company.net

Upvotes: 2

Related Questions