I have an ansible inventory that looks something like:
all:
children:
nodes:
vars:
bmc_user: root
bmc_pass: secret
hosts:
node1.example.com:
bmc_addr: node1-bmc.example.com
node2.example.com:
bmc_addr: node2-bmc.example.com
For running something like ipmitool, I can simply delegate the task to localhost, like this:
- hosts: all
gather_facts: false
tasks:
- delegate_to: localhost
command: >-
ipmitool -I lanplus -H {{ bmc_addr }} -U {{ bmc_user }} -P {{ bmc_pass }} power off
Occasionally, I need to interact with the bmc using ssh. Thsi is tricky, because typically this requires password authentication. I want to write something like this:
- hosts: all
gather_facts: false
tasks:
- delegate_to: "{{ bmc_addr }}"
command: >-
racadm set iDRAC.IPMILan.Enabled Enable
...but this won't work, because the credentials required to access the bmc are not the same as the credentials necessary to access the host. I would like to be able to do something like this in my inventory:
all:
children:
nodes:
vars:
bmc_user: root
bmc_pass: secret
hosts:
node1.example.com:
bmc_addr: node1-bmc.example.com
node2.example.com:
bmc_addr: node2-bmc.example.com
nodes_bmc:
vars:
ansible_user: root
ansible_ssh_pass: secret
hosts:
node1-bmc.example.com:
node2-bmc.example.com:
...but I would like the hosts in the nodes_bmc group to be populated
dynamically from the bmc_addr values in the nodes group, rather
than having to specify them manually.
I've been puzzling over this for a bit, and the only solution I've come up with is to write some tooling that reads the ansible inventory and then generates a new static inventory containing the necessary entries. That seems clunky, and requires ensuring that the "generate bmc inventory" tool is run whenever the main inventory is modified.