TL;DR Is there an easy way to set the become password for all hosts in a particular inventory file without using the all group?
I'm an Ansible noob so maybe there's a better way to construct my inventory files, but here is my problem: I have groups of hosts in multiple inventory files. Each inventory file is structured with the same group names, but with different hosts. Currently I'm using the all
group to set the become password per inventory file. If I run a playbook against one inventory then all is well.
The problem comes in when I try run a playbook on multiple inventory files. From what I can tell, the become password in the last inventory file that gets parsed is used for all hosts in all
group. I realize that I can create other groups in each inventory to get around this, but it makes each inventory overly complicated IMO.
I was expecting the scope of all
to be limited to that particular inventory, but it does make sense to have the ability to set variables for all hosts across all inventories. However I'm a bit surprised there isn't an easier way to set a variable for all hosts in an inventory and limit the scope to only that inventory.
Q: " ... the scope of all to be limited to that particular inventory ... easier way to set a variable for all hosts in an inventory and limit the scope to only that inventory."
A: The special variable inventory_file keeps
The file name of the inventory source in which the inventory_hostname was first defined.
For example, given the inventory
shell> tree inventory/
inventory/
├── 01_hosts
├── 02_hosts
└── 03_hosts
shell> cat inventory/01_hosts
[g1]
test_11
test_12
shell> cat inventory/02_hosts
[g2]
test_21
test_22
shell> cat inventory/03_hosts
[g3]
test_31
test_32
The play
- hosts: all
tasks:
- debug:
var: inventory_file | basename
gives
ok: [test_11] =>
inventory_file | basename: 01_hosts
ok: [test_12] =>
inventory_file | basename: 01_hosts
ok: [test_21] =>
inventory_file | basename: 02_hosts
ok: [test_31] =>
inventory_file | basename: 03_hosts
ok: [test_22] =>
inventory_file | basename: 02_hosts
ok: [test_32] =>
inventory_file | basename: 03_hosts
Create a dictionary with the passwords and declare ansible_become_password
shell> cat inventory/group_vars/all/become_password_dict.yml
become_password_dict:
01_hosts: become password 01
02_hosts: become password 02
03_hosts: become password 03
ansible_become_password: "{{ become_password_dict[inventory_file | basename] }}"
Note: Encrypting files comprising passwords is recommended.
Then the play does what you want set a variable for all hosts in an inventory and limit the scope to only that inventory
shell> cat pb.yml
- hosts: all
tasks:
- debug:
var: ansible_become_password
gives (abridged)
k: [test_12] =>
ansible_become_password: become password 01
ok: [test_21] =>
ansible_become_password: become password 02
ok: [test_11] =>
ansible_become_password: become password 01
ok: [test_31] =>
ansible_become_password: become password 03
ok: [test_22] =>
ansible_become_password: become password 02
ok: [test_32] =>
ansible_become_password: become password 03
You can limit the groups. For example,
shell> ansible-playbook -i inventory pb.yml -l g1,g3
...
ok: [test_11] =>
ansible_become_password: become password 01
ok: [test_31] =>
ansible_become_password: become password 03
ok: [test_12] =>
ansible_become_password: become password 01
ok: [test_32] =>
ansible_become_password: become password 03
To run a playbook on multiple inventory files
use the option -i
multiple times. For example,
shell> ansible-playbook pb.yml -i inventory/01_hosts -i inventory/03_hosts
...