Reputation: 21
I have a task , in which I need to select the target environment/hosts amongst the multiple inventory files placed in different folders under inventories/ directory. The selection is based on the version passed as a variable.
inventories/
preprod/
group_vars/
hosts.ini
...
systest/
group_vars/
hosts.ini
...
uat/
group_vars/
hosts.ini
...
So if the version varaiable is 1.x.x then the hosts.ini under preprod should be selected, if its 2.x.x then the hosts.ini under systest should be selected and if its 3.x.x the hosts.ini under uat should be selected.
---
- name: Select hosts from multiple inventories based on version passed as a variable
hosts: all
vars:
version: '1.0'
tasks:
- name: Get hosts from first inventory
set_fact:
hosts_1: "{{ groups['inventory_1'] | selectattr('version', 'equalto', version) | map(attribute='hostname') | list }}"
- name: Get hosts from second inventory
set_fact:
hosts_2: "{{ groups['inventory_2'] | selectattr('version', 'equalto', version) | map(attribute='hostname') | list }}"
- name: Merge hosts from both inventories
set_fact:
hosts: "{{ hosts_1 + hosts_2 }}"
- name: Run tasks with hosts
debug:
msg: "{{ item }}"
loop: "{{ hosts }}"
Upvotes: 1
Views: 1318
Reputation: 67984
Short answer: Copy the inventory file in the first play, refresh_inventory, and use it in the second play. Unfortunately, this does not refresh group_vars from the directories. As a workaround put the group_vars into the inventory files.
Details: Given the project for testing
shell> tree .
.
├── ansible.cfg
├── hosts.env
├── inventory
│ ├── preprod
│ │ └── hosts.ini
│ ├── systest
│ │ └── hosts.ini
│ └── uat
│ └── hosts.ini
└── pb.yml
4 directories, 6 files
Put the group_vars into the inventory files
shell> cat inventory/preprod/hosts.ini
[all]
preprod1
preprod2
preprod3
[all:vars]
env_gv=preprod
shell> cat inventory/systest/hosts.ini
systest1
systest2
systest3
[all:vars]
env_gv=systest
shell> cat inventory/uat/hosts.ini
[all]
uat1
uat2
uat3
[all:vars]
env_gv=uat
The playbook
shell> cat pb.yml
- hosts: localhost
vars:
envs:
1: preprod
2: systest
3: uat
env: "{{ envs[version.split('.').0|int] }}"
tasks:
- debug:
msg: "Use environment: {{ env }}"
- copy:
src: "{{ playbook_dir }}/inventory/{{ env }}/hosts.ini"
dest: "{{ playbook_dir }}/hosts.env"
- meta: refresh_inventory
- hosts: all
tasks:
- block:
- debug:
var: ansible_play_hosts_all
- debug:
var: env_gv
run_once: true
gives
version=1.0 works in the environment preprod
shell> ansible-playbook -i hosts.env -e version=1.0 pb.yml
PLAY [localhost] ****************************************************************************************
TASK [debug] ********************************************************************************************
ok: [localhost] =>
msg: 'Use environment: preprod'
TASK [copy] *********************************************************************************************
changed: [localhost]
TASK [meta] *********************************************************************************************
PLAY [all] **********************************************************************************************
TASK [debug] ********************************************************************************************
ok: [preprod1] =>
ansible_play_hosts_all:
- preprod1
- preprod2
- preprod3
TASK [debug] ********************************************************************************************
ok: [preprod1] =>
env_gv: preprod
PLAY RECAP **********************************************************************************************
localhost: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
preprod1: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
version=2.0 works in the environment systest
shell> ansible-playbook -i hosts.env -e version=2.0 pb.yml
PLAY [localhost] ****************************************************************************************
TASK [debug] ********************************************************************************************
ok: [localhost] =>
msg: 'Use environment: systest'
TASK [copy] *********************************************************************************************
changed: [localhost]
TASK [meta] *********************************************************************************************
PLAY [all] **********************************************************************************************
TASK [debug] ********************************************************************************************
ok: [systest1] =>
ansible_play_hosts_all:
- systest1
- systest2
- systest3
TASK [debug] ********************************************************************************************
ok: [systest1] =>
env_gv: systest
PLAY RECAP **********************************************************************************************
localhost: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
systest1: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
version=3.0 works in the environment uat
shell> ansible-playbook -i hosts.env -e version=3.0 pb.yml
PLAY [localhost] ****************************************************************************************
TASK [debug] ********************************************************************************************
ok: [localhost] =>
msg: 'Use environment: uat'
TASK [copy] *********************************************************************************************
changed: [localhost]
TASK [meta] *********************************************************************************************
PLAY [all] **********************************************************************************************
TASK [debug] ********************************************************************************************
ok: [uat1] =>
ansible_play_hosts_all:
- uat1
- uat2
- uat3
TASK [debug] ********************************************************************************************
ok: [uat1] =>
env_gv: uat
PLAY RECAP **********************************************************************************************
localhost: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
uat1: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Example. Precedence of group_vars. YAML format.
shell> tree .
.
├── ansible.cfg
├── group_vars
│ └── all.yml
├── hosts
├── inventories
│ ├── preprod
│ │ └── hosts
│ ├── systest
│ │ └── hosts
│ └── uat
│ └── hosts
├── inventory
│ ├── group_vars
│ │ └── all.yml
│ └── hosts
└── pb.yml
7 directories, 9 files
shell> cat group_vars/all.yml
env_gv3: playbook group_vars/all
shell> cat inventory/group_vars/all.yml
env_gv2: inventory group_vars/all
shell> cat inventories/preprod/hosts
all:
hosts:
preprod1:
preprod2:
preprod3:
vars:
env_gv1: preprod1 inventory file group_vars
env_gv2: preprod2 inventory file group_vars
env_gv3: preprod3 inventory file group_vars
shell> cat inventories/systest/hosts
all:
hosts:
systest1:
systest2:
systest3:
vars:
env_gv1: systest1 inventory file group_vars
env_gv2: systest2 inventory file group_vars
env_gv3: systest3 inventory file group_vars
shell> cat inventories/uat/hosts
all:
hosts:
uat1:
uat2:
uat3:
vars:
env_gv1: uat1 inventory file group_vars
env_gv2: uat2 inventory file group_vars
env_gv3: uat3 inventory file group_vars
shell> cat pb.yml
- hosts: localhost
vars:
envs:
1: preprod
2: systest
3: uat
env: "{{ envs[version.split('.').0|int] }}"
tasks:
- debug:
msg: "Use environment: {{ env }}"
- copy:
src: "{{ playbook_dir }}/inventories/{{ env }}/hosts"
dest: "{{ playbook_dir }}/inventory/hosts"
- meta: refresh_inventory
- hosts: all
tasks:
- block:
- debug:
var: ansible_play_hosts_all
- debug:
msg: |
env_gv1: {{ env_gv1 }}
env_gv2: {{ env_gv2 }}
env_gv3: {{ env_gv3 }}
run_once: true
shell> ansible-playbook -i inventory/hosts -e version=2.0 pb.yml
shows that variable precedence:
works as expected
PLAY [localhost] ****************************************************************************************
TASK [debug] ********************************************************************************************
ok: [localhost] =>
msg: 'Use environment: systest'
TASK [copy] *********************************************************************************************
changed: [localhost]
TASK [meta] *********************************************************************************************
PLAY [all] **********************************************************************************************
TASK [debug] ********************************************************************************************
ok: [systest1] =>
ansible_play_hosts_all:
- systest1
- systest2
- systest3
TASK [debug] ********************************************************************************************
ok: [systest1] =>
msg: |-
env_gv1: systest1 inventory file group_vars
env_gv2: inventory group_vars/all
env_gv3: playbook group_vars/all
PLAY RECAP **********************************************************************************************
localhost: ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
systest1: ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Upvotes: 2