I'm trying to setup an role for rolling out users. I have a list of users with their variables and I would like to only roll out authorized_key when the variable pubkey
is set. Here is my code:
provisioning_user:
- name: ansible
state: present
pubkeys:
- 'ssh-rsa peter-key-1 peter@key1'
- 'ssh-rsa peter-key-3 peter@key3'
root: true
# removes directorys associated with the user
remove: true
create_home: true
comment: Deploy user for ansible
# If set to true when used with home: , attempt to move the user’s old home
# directory to the specified directory if it isn’t there already and the
# old home exists.
#non_unique: false
#uid: 11
#group:
groups: admin, developer
# If false, user will only be added to the groups specified in groups,
# removing them from all other groups.
append: yes
password: '!'
#ssh_public_keyfiles: ['ansible.pub', 'patrick.pub']
#key: ssh-ed25519 AAAAC3NzetfqeafaC1lZDI1NTE5AAAAIHu28wqv0r4aqoK1obosoLCBP0vqZj8MIlkvpAbXv0LL
#key_options:
#key_comment:
key_exclusive: true
key_manage_dir: true
- name: testuser2
state: present
# removes directorys associated with the user
#remove: false
create_home: yes
comment: Deploy user for ansible
As you see, the second user has no attribute pubkeys
. Here is my Ansible code:
- name: test key
authorized_key:
user: "{{ item.name }}"
key: "{{ '\n'.join(provisioning_user|map(attribute='pubkeys')|flatten) }}"
comment: "{{ item.key_comment | default('managed by ansible') }}"
state: "{{ item.state | default('true') }}"
exclusive: "{{ item.key_exclusive | default('true') }}"
key_options: "{{ item.key_options | default(omit) }}"
manage_dir: "{{ item.manage_dir | default('true') }}"
loop: "{{ provisioning_user }}"
when: item.pubkeys is defined
Thats what Ansible says:
fatal: [cloud.xxx.xxx]: FAILED! =>
msg: |-
The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'pubkeys'
The error appears to be in '/home/xxx/gitlab.com/xxx/ansible/roles/provisioning/tasks/keys.yaml': line 2, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
---
- name: test key
^ here
Can you please help me getting the when condition work? I only want this task to run if a user has pubkeys defined, when not just skipping it.
This doesn't make any sense:
key: "{{ '\n'.join(provisioning_user|map(attribute='pubkeys')|flatten) }}"
You're looping over the contents of provisioning_user
in this task; provisioning_user
doesn't have a key pubkeys
, rather, each individual item in that list may have a pubkeys
value. So you'd want something like:
key: "{{ '\n'.join(item.pubkeys) }}"
Making the complete task look like:
- name: test key
authorized_key:
user: "{{ item.name }}"
key: "{{ '\n'.join(item.pubkeys) }}"
comment: "{{ item.key_comment | default('managed by ansible') }}"
state: "{{ item.state | default('true') }}"
exclusive: "{{ item.key_exclusive | default('true') }}"
key_options: "{{ item.key_options | default(omit) }}"
manage_dir: "{{ item.manage_dir | default('true') }}"
loop: "{{ provisioning_user }}"
when: item.pubkeys is defined
Running the above in a test environment produces:
TASK [test key] *****************************************************************************************
changed: [node0] => (item={'name': 'ansible', 'state': 'present', 'pubkeys': ['ssh-rsa peter-key-1 peter@key1', 'ssh-rsa peter-key-3 peter@key3'], 'root': True, 'remove': True, 'create_home': True, 'comment': 'Deploy user for ansible', 'groups': 'admin, developer', 'append': True, 'password': '!', 'key_exclusive': True, 'key_manage_dir': True})
skipping: [node0] => (item={'name': 'testuser2', 'state': 'present', 'create_home': True, 'comment': 'Deploy user for ansible'})
...which is I think what you want.