I want to do something very similar as mentioned in How can I have a nested loop with a fileglob pattern? except that the list of files is a glob pattern which refers to the items from the outer loop.
My (failing) code so far:
- name: Deploy authorized_keys files for users
authorized_key:
user: "{{ item }}"
key: "{{ query('fileglob', 'ssh-pub-keys/{{ item }}/*.pub') }}"
with_list:
- user1
- user2
The directory ssh-pub-keys
looks as follows:
ssh-pub-keys
├── user1
│ ├── hostA_id_ecdsa.pub
│ ├── hostA_id_ed25519.pub
│ ├── hostB_id_ecdsa.pub
│ ├── hostB_id_ed25519.pub
│ └── hostB_id_rsa.pub
└── user2
├── hostC_id_ecdsa.pub
├── hostC_id_rsa.pub
├── hostD_id_ecdsa.pub
└── hostD_id_ed25519.pub
The error message looks like this:
failed: [somehost] (item=user1) => {"changed": false, "item": "user1", "msg": "invalid key specified: ['…/ssh-pub-keys/user1/hostA_id_ecdsa.pub', '…/ssh-pub-keys/user1/hostA_id_ed25519.pub', …]"}
failed: [somehost] (item=user2) => {"changed": false, "item": "user2", "msg": "invalid key specified: ['…/ssh-pub-keys/user2/hostC_id_ecdsa.pub', '…/ssh-pub-keys/user2/hostC_id_rsa.pub', …]"}
I don't seem to be able to use with_nested
as I can't refer from the one list to other one.
Also tried Ansible/Jinja2 filters like loop: {{ ['user1','user2'] | product(query(('fileglob', 'ssh-pub-keys/{{ ??? }}/*.pub'')) | list }}
, but didn't figure out how to refer to the items from the first list inside product(…)
…
Another try was to use two tasks with the second referring to the first's registered output, but I didn't figure out how to make shell output into a proper data structure (output split by space, but keeping the information which input item was used) again:
- name: Enumerate all authorized_keys files for all users
shell: "echo ssh-pub-keys/{{ item }}/*.pub"
with_list:
- user1
- user2
register: keyfiles
Anyone knows how these kind of tasks are implemented properly?
P.S.: Using Ansible 2.7.7 as available in Debian 10 Buster (current Debian stable release).