Reputation: 37
I would like to setup several ssh public keys for users, today I have something that can already setup only one key:
users:
user1:
comment: "User 1"
sshkey: "ssh-rsa ******** user1"
state: present
user2:
comment: "User 2"
sshkey: "ssh-rsa ******** user2"
state: present
user3:
comment: "User 3"
sshkey: "ssh-rsa ******** user3"
state: present
and my play is:
- name: set authorized_keys
ansible.posix.authorized_key:
user: "{{ item.key }}"
state: "{{ item.value.state }}"
key: "{{ item.value.sshkey }}"
with_dict: "{{ users }}"
when: item.value.state == "present" and item.value.sshkey is defined
I would like to be able in my users
var to pass several keys for one user, something like:
users:
user1:
comment: "User 1"
sshkeys:
- ssh-rsa ******** user1.key
state: present
user2:
comment: "User 2"
sshkeys:
- ssh-rsa ******** user2.key-a
- ssh-rsa ******** user2.key-b
state: present
user3:
comment: "User 3"
sshkeys:
- ssh-rsa ******** user2.key-a
- ssh-rsa ******** user2.key-b
- ssh-rsa ******** user3.key-c
state: present
But I don't have an idea how I should iterate over this sshkeys
list
Upvotes: 2
Views: 740
Reputation: 68144
In the example, you test the existence of the attribute sshkeys. I assume this is because this attribute might be missing in the dictionary. Let's remove this attribute from user3 for testing users:
user1:
comment: User 1
sshkeys:
- ssh-rsa ******** user1.key
state: present
user2:
comment: User 2
sshkeys:
- ssh-rsa ******** user2.key-a
- ssh-rsa ******** user2.key-b
state: present
user3:
comment: User 3
state: present
Q: "How should I iterate over this sshkeys list?"
A1: It's not necessary to iterate the list of sshkeys. It's possible to configure them all in one step. Quoting from exclusive:
Multiple keys can be specified in a single key string value by separating them by newlines.
For example
- debug:
msg: |-
user: {{ item.key }}
state: {{ item.value.state }}
key: {{ item.value.sshkeys|join('\n') }}
loop: "{{ users|dict2items }}"
when:
- item.value.state == 'present'
- item.value.sshkeys|d([])|length > 0
gives (abridged)
msg: |-
user: user1
state: present
key: ssh-rsa ******** user1.key
msg: |-
user: user2
state: present
key: ssh-rsa ******** user2.key-a\nssh-rsa ******** user2.key-b
If you want to iterate the keys, proceed to the next option.
A2: As a first step add the attribute sshkeys if missing
- set_fact:
users: "{{ dict(_keys|zip(_vals_update)) }}"
vars:
_keys: "{{ users.keys()|list }}"
_vals: "{{ users.values()|list }}"
_vals_update: "{{ [{'sshkeys': []}]|
product(_vals)|
map('combine')|list }}"
gives
users:
user1:
comment: User 1
sshkeys:
- ssh-rsa ******** user1.key
state: present
user2:
comment: User 2
sshkeys:
- ssh-rsa ******** user2.key-a
- ssh-rsa ******** user2.key-b
state: present
user3:
comment: User 3
sshkeys: []
state: present
Now, iterate the dictionary with subelements
- debug:
msg: >-
user: {{ item.0.key }}
state: {{ item.0.value.state }}
key: {{ item.1 }}
with_subelements:
- "{{ users|dict2items }}"
- value.sshkeys
when: item.0.value.state == 'present'
gives (abridged)
msg: 'user: user1 state: present key: ssh-rsa ******** user1.key'
msg: 'user: user2 state: present key: ssh-rsa ******** user2.key-a'
msg: 'user: user2 state: present key: ssh-rsa ******** user2.key-b'
Upvotes: 2