So I'm sort of stuck on an issue. Essentially, I would like to run a nested loop with both a list and a dictionary, and I can't seem to figure out how.
My use case is running a playbook that will generate SSH certificates by signing public keys with a list of principals.
I have a list of hosts (group called bastionHosts) that act as jump-hosts. These hosts have end-users and their SSH keypair on them.
[bastionHosts]
10.100.0.10
10.100.0.11
I also have a dictionary of users and their SSH principals. The dictionary looks like this:
users:
webuser01: "webservers-principal"
dbuser01: "dbservers-principal"
webadmin01: "webservers-principal"
I use the fetch module to download the public keys ("id_ecdsa.pub" for each user. This creates a directory structure that looks like: "/tmp/public_keys/<>/home/<< username>>/.ssh/id_ecdsa.pub
For example, fetching the public key for webuser01 on bastion 10.100.0.10 would place the key into /tmp/public_keys/10.100.0.10/home/webuser01/.ssh/id_ecdsa.pub on the ansible host.
My goal is to recurse down into this directory structure and sign each public key with the appropriate principals, but I can't figure out how to do that.
The code below would work if I was only fetching one set of files and it was a flat fetch (i.e. the directory structure for each host wasn't used). item.key is the username, and item.value is the set of principals.
- name: create signed certificates with appropriate principals
command: ssh-keygen -s /etc/ssh/CA/CA -I {{ item.key }} -n {{ item.value }} -V +1d /tmp/public_keys/{{ item.key }}.pub
with_dict:
"{{ users }}"
I need a way to also specify the host from the build-in groups.bastionHosts so that I can traverse the directory structure.The below code is a rough idea of what I'm looking to do, but I can't find a way to get with_nested to work with a list and a dictionary.
- name: create signed certificates with appropriate principals
command: ssh-keygen -s /etc/ssh/CA/CA -I {{ item.key }} -n {{ item[1].value }} -V +1d /tmp/public_keys/{{ item[0] }}/home/{{ item[1].key }}/.ssh/id_ecdsa.pub
with_nested:
- "{{ groups.bastionHosts }}
- "{{ users }}"
Essentially, if the above worked, it would walk down into each directory for each bastion host (item0) and user (item[1].key) and sign the key with the appropriate principals (item[1].value). However, this doesn't work. I get errors that item[1] doesn't have an element "value." I imagine this is because with_nested is supposed to work with lists, and not dictionaries.
So basically: is there a way to get with_nested to work with dictionaries and lists such that I can reference elements of a list while also referencing items within a dictionary? If not, am I perhaps making this too complicated and there's an easier way? Thanks in advance!
There is a hack out there: you can make a list from dict with
dictsort
filter: