Reputation: 113
I'm running into the issue (feature?) described in Ansible group vars priority , presumably because I've gone about structuring my inventory incorrectly.
The idea was to have two tasks, which apply to all 'routers' or 'firewalls' as defined in the inventory. This part works fine -- Ansible correctly parses the inventory and distinguishes between the two.
The problem is that due to the way the inventory is parsed, it's using the same ansible_user and ansible_password for every customer group. Which apparently makes sense based on the documentation:
When groups of the same parent/child level are merged, it is done alphabetically, and the last group loaded overwrites the previous groups. For example, an a_group will be merged with b_group and b_group vars that match will overwrite the ones in a_group.
Can anyone advise how I should correct this? If I change the 'routers' and 'firewalls' subgroups to be unique, e.g., custA_routers, custB_routers, then it behaves as expected. However then I think I have to write tasks scoped to each of those subgroups. Note that all hosts are unique IP addresses.
Playbook:
---
- name: Check routers
hosts: routers
tasks:
- name: Do stuff.
<commands>
- name: Check firewalls
hosts: firewalls
tasks:
- name: Do stuff.
<commands>
Inventory:
all:
vars:
ansible_connection: network_cli
ansible_network_os: ios
children:
customerOne:
vars:
ansible_user: userOne
ansible_password: <vaulted pass>
children:
routers:
hosts:
x.x.x.x
y.y.y.y
firewalls:
vars:
ansible_network_os: asa
hosts:
z.z.z.z
customerTwo:
vars:
ansible_user: userTwo
ansible_password: <vaulted pass>
children:
routers:
hosts:
x.x.x.x
y.y.y.y
firewalls:
vars:
ansible_network_os: asa
hosts:
z.z.z.z
Upvotes: 1
Views: 1245
Reputation: 68034
It's possible to simplify the inventory
all:
vars:
ansible_connection: network_cli
ansible_network_os: ios
children:
routers:
hosts:
x.x.x.x
y.y.y.y
firewalls:
vars:
ansible_network_os: asa
hosts:
z.z.z.z
and put the authentication data into a separate variable. Put it where it fits best. This might be 'all: vars:' section in the inventory, 'vars:' section in a playbook, 'group_vars/all' directory ...
auth:
customerOne:
ansible_user: userOne
ansible_password: <vaulted pass>
customerTwo:
ansible_user: userTwo
ansible_password: <vaulted pass>
Add a play in the top of the playbook and assign the variables according to the external variable customer
- name: Read variables
gather_facts: false
hosts: routers
tasks:
- set_fact:
ansible_user: "{{ auth[customer].ansible_user }}"
ansible_password: "{{ auth[customer].ansible_password }}"
run_once: true
- name: Check routers
hosts: routers
tasks:
- name: Do stuff.
<commands>
Run the playbook and specify the customer
ansible-playbook playbook.yml -e "customer=customerTwo"
Upvotes: 2
Reputation: 12674
I thiink it is ideal to create two separate inventory, customerOneInventory.yaml and customerTwo.yaml or router.yaml and firewalls.yaml.. up to your need. You'll just specify the inventory file you need during ansible playbook run.
ansible-playbook heat-check-playbook.yaml -i customerOneInventory.yaml
Upvotes: 0