2

When I try to loop (with Ansible 2.6 loop) with subelements through all public keys of a list of users and encounter a user which has no public keys defined:

- authorized_key: user: "{{ item.0.username }}" state: present key: "{{ item.1.pub_key }}" loop: "{{ users | subelements('ssh_pub_keys') | default ([]) }}" loop_control: label: "{{ item.username }}" 

I'm getting the following error: the key 'ssh_pub_keys' should point to a list, got None

When I try to use skip_missing like this:

- authorized_key: user: "{{ item.0.username }}" state: present key: "{{ item.1.pub_key }}" loop: "{{ lookup('subelements', users, 'ssh_pub_keys', {'skip_missing': True})}}" loop_control: label: "{{ item.username }}" 

I get this error: 'list object' has no attribute 'username'

This could be the users list:

users: - username: usera ssh_pub_keys: - from: home pub_key: kdzadizajdiazjd - from: work pub_key: dzadadazdzadzad - username: userb ssh_pub_keys: - from: home pub_key: kdzadizajdiazjd - from: work pub_key: dzadadazdzadzad - username: userc - username: userd ssh_pub_keys: - from: home pub_key: kdzadizajdiazjd - from: work pub_key: dzadadazdzadzad 

How can I make the loop with subelements to go to the next user without throwing an error when a user is encountered which has no ssh_pub_keys list?

1 Answer 1

2

Q: "Error: the key 'ssh_pub_keys' should point to a list, got None."

A: You might want to use lookup and set 'skip_missing': True.

 loop: "{{ lookup('subelements', users, 'ssh_pub_keys', {'skip_missing': True}) }}" 

Optionally, you can use subelements as a filter. The below loop gives the same results

 loop: "{{ users | subelements('ssh_pub_keys', skip_missing=true) }}" 

Q: "Error: 'list object' has no attribute 'username'"

A: The index is missing. Please fix it.

 label: "{{ item.0.username }}" 

Example of a complete playbook for testing

- hosts: localhost vars: users: - username: foo ssh_pub_keys: - pub_key: k1 - pub_key: k2 - username: bar - username: baz ssh_pub_keys: - pub_key: k1 - pub_key: k2 tasks: - debug: msg: "{{ item.0.username }} {{ item.1.pub_key }}" loop: "{{ users | subelements('ssh_pub_keys', skip_missing=true) }}" loop_control: label: "{{ item.0.username }}" 

gives (abridged)

 msg: foo k1 msg: foo k2 msg: baz k1 msg: baz k2 

Note: The option key allows multiple keys. You don't have to iterate ssh_pub_keys. For example,

 - debug: msg: | user: "{{ item.username }}" key: | {{ item.ssh_pub_keys | map(attribute='pub_key') | join('\n') }} loop: "{{ users | selectattr('ssh_pub_keys', 'defined') }}" 

gives (abridged)

 user: "foo" key: | k1\nk2 user: "baz" key: | k1\nk2 
3
  • Thanks, but when I try 'loop: "{{lookup('subelements', users, 'ssh_pub_keys', {'skip_missing': True})}}"' I get the error: 'list object' has no attribute 'username' Commented Jan 14, 2019 at 20:20
  • It seems like when I remove the loop control, your solution works. Feel free to add that to your answer. Commented Jan 15, 2019 at 15:50
  • I've added the answer. Commented Jun 28, 2021 at 9:57

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.