Reputation: 103
I have below ansible inventory structure:
[app1]
labhost1 ansible_host=1.1.1.1 tag=master
labhost2 ansible_host=1.1.1.2 tag=slave
labhost3 ansible_host=1.1.1.3 tag=slave
labhost4 ansible_host=1.1.1.4 tag=master
labhost5 ansible_host=1.1.1.5 tag=slave
labhost6 ansible_host=1.1.1.6 tag=slave
[DC1]
dc1_app1
[DC2]
dc2_app1
[dc1_app1]
labhost1 ansible_host=1.1.1.1 tag=master
labhost2 ansible_host=1.1.1.2 tag=slave
labhost3 ansible_host=1.1.1.3 tag=slave
[dc2_app1]
labhost4 ansible_host=1.1.1.4 tag=master
labhost5 ansible_host=1.1.1.5 tag=slave
labhost6 ansible_host=1.1.1.6 tag=slave
and group_vars
file below:
DC1.yml
---
location: country1
DC2.yml
---
location: country2
When running a playbook on labhost2
, I like to extract the IP address of the master device in the same datacenter in which the host labhost2
is located.
I tried below expression
- set_fact:
masterIP: "{{ groups['app1'] | map('extract', hostvars) | selectattr('location', 'eq', location) | selectattr('tag', 'eq', 'master') | map(attribute='ansible_host') }}"
It should return 1.1.1.1
as value of the variable masterIP
but it shows:
VARIABLE IS UNDEFINED
Upvotes: 0
Views: 256
Reputation: 68189
From the logic of the question, I can only assume that you run the playbook for the group app1
- hosts: app1
Iterate the 'dc*' groups that belong to the group of applications and create the dictionary of masters, e.g.
- set_fact:
dc_masters: "{{ dc_masters|d({})|combine({item: _dict.master}) }}"
loop: "{{ groups|select('match', 'dc[\\d+]_app1') }}"
vars:
_hosts: "{{ groups[item] }}"
_tags: "{{ _hosts|map('extract', hostvars, 'tag') }}"
_dict: "{{ dict(_tags|zip(_hosts)) }}"
run_once: true
gives
dc_masters:
dc1_app1: labhost1
dc2_app1: labhost4
Then you can use this dictionary and find the masters for the slaves, e.g.
- debug:
msg: "slave: {{ inventory_hostname }} master: {{ dc_masters[dc] }}"
vars:
dc: "{{ group_names|difference(['app1'])|first }}"
when: tag == 'slave'
gives
TASK [debug] **************************************************************
skipping: [labhost1]
skipping: [labhost4]
ok: [labhost2] =>
msg: 'slave: labhost2 master: labhost1'
ok: [labhost3] =>
msg: 'slave: labhost3 master: labhost1'
ok: [labhost6] =>
msg: 'slave: labhost6 master: labhost4'
ok: [labhost5] =>
msg: 'slave: labhost5 master: labhost4'
Fit the expression dc: ...
to your needs if there are more groups a slave belongs to.
Upvotes: 1