I'm trying to run a database.yaml
playbook that has the databases group as hosts, which contains all the db-* hosts from the inventory.
- name: Install PostgreSQL
hosts: databases
---
all:
children:
group1:
children:
subgroup1:
hosts:
db-host1:
ansible_host: 192.168.0.1
cache-host2:
ansible_host: 192.168.0.2
subgroup2:
hosts:
db-host3:
ansible_host: 192.168.0.3
cache-host4:
ansible_host: 192.168.0.4
group2:
children:
subgroup1:
hosts:
db-host5:
ansible_host: 192.168.0.5
cache-host6:
ansible_host: 192.168.0.6
subgroup2:
hosts:
db-host7:
ansible_host: 192.168.0.7
cache-host8:
ansible_host: 192.168.0.8
databases:
hosts:
db-host1:
db-host3:
db-host5:
db-host7:
cache:
hosts:
cache-host2:
cache-host4:
cache-host6:
cache-host8:
But I need to run only on those hosts that are in the group “group1,subgroup1”, I can not bind to the name of the host, because in the group subgroup1
hosts db-* can be many.
At startup with limits specified:
ansible-playbook -i inventory/demo database.yml --limit "group1,subgroup1"
The playbook runs on all hosts in the “databases” group Could you please tell me how to properly run the playbook on multiple groups?
Ansible inventory is flat. Given your inventory in the file hosts the below command
shell> ansible-inventory -i hosts --list --yaml
gives
all:
children:
cache:
hosts:
cache-host2: {}
cache-host4: {}
cache-host6: {}
cache-host8: {}
databases:
hosts:
db-host1: {}
db-host3: {}
db-host5: {}
db-host7: {}
group1:
children:
subgroup1:
hosts:
cache-host2:
ansible_host: 192.168.0.2
cache-host6:
ansible_host: 192.168.0.6
db-host1:
ansible_host: 192.168.0.1
db-host5:
ansible_host: 192.168.0.5
subgroup2:
hosts:
cache-host4:
ansible_host: 192.168.0.4
cache-host8:
ansible_host: 192.168.0.8
db-host3:
ansible_host: 192.168.0.3
db-host7:
ansible_host: 192.168.0.7
group2:
children:
subgroup1: {}
subgroup2: {}
You can see that the content of the groups is merged. Ansible doesn't keep the structure of the subdictionaries. Instead, the content of both subgroup1 and subgroup2 are merged. Because both group1 and group2 keep subgroup1 and subgroup2 the content of group1 and group2 is equivalent. You can test it
- hosts: all
tasks:
- debug:
msg: |
{{ groups.group1 }}
{{ groups.group2 }}
{{ groups.subgroup1 }}
{{ groups.subgroup2 }}
run_once: true
gives (abridged)
shell> ansible-playbook -i hosts pb.yml
PLAY [all] **********************************************************************************************************
TASK [debug] ********************************************************************************************************
ok: [db-host1] =>
msg: |-
['db-host1', 'cache-host2', 'db-host5', 'cache-host6', 'db-host3', 'cache-host4', 'db-host7', 'cache-host8']
['db-host1', 'cache-host2', 'db-host5', 'cache-host6', 'db-host3', 'cache-host4', 'db-host7', 'cache-host8']
['db-host1', 'cache-host2', 'db-host5', 'cache-host6']
['db-host3', 'cache-host4', 'db-host7', 'cache-host8']
Note: Look at the Common patterns. The expression group1:&subgroup1
is an intersection of groups and means:
any hosts in group1 that are also in subgroup1
This expression doesn't make sense in this inventory because subgroup1 is a subset of group1.
As a result, there is no such thing as group1.subgroup1
or group2.subgroup1
in the Ansible inventory. Instead, you can create a flat structure of groups. For example,
shell> cat hosts2
all:
children:
group1_subgroup1:
hosts:
db-host1:
ansible_host: 192.168.0.1
cache-host2:
ansible_host: 192.168.0.2
group1_subgroup2:
hosts:
db-host3:
ansible_host: 192.168.0.3
cache-host4:
ansible_host: 192.168.0.4
group2_subgroup1:
hosts:
db-host5:
ansible_host: 192.168.0.5
cache-host6:
ansible_host: 192.168.0.6
group2_subgroup2:
hosts:
db-host7:
ansible_host: 192.168.0.7
cache-host8:
ansible_host: 192.168.0.8
databases:
hosts:
db-host1:
db-host3:
db-host5:
db-host7:
cache:
hosts:
cache-host2:
cache-host4:
cache-host6:
cache-host8:
Then, the play below
- hosts: all
tasks:
- debug:
msg: |
{{ groups.group1_subgroup1 }}
{{ groups.group1_subgroup2 }}
{{ groups.group2_subgroup1 }}
{{ groups.group2_subgroup2 }}
run_once: true
gives (abridged)
shell> ansible-playbook -i hosts2 pb.yml
PLAY [all] **********************************************************************************************************
TASK [debug] ********************************************************************************************************
ok: [db-host1] =>
msg: |-
['db-host1', 'cache-host2']
['db-host3', 'cache-host4']
['db-host5', 'cache-host6']
['db-host7', 'cache-host8']