Is it possible to use Ansible authorized_key exclusive with multiple keys?

Valien picture Valien · Aug 10, 2016 · Viewed 12k times · Source

I'm fairly new in using Ansible and have been reading here and google and haven't found an answer yet.

My scenario is that I have 1 user on a server but 2-3 different pub keys that need to put in it's authorized_keys file.

I can successfully remove all keys, or add all keys with this script:

---
  - hosts: all

 tasks:
  - name: update SSH keys
    authorized_key:
     user: <user>
     key: "{{ lookup('file', item) }}"
     state: present
     #exclusive: yes
    with_fileglob:
      - ../files/pub_keys/*.pub

With the present flag it reads and adds all the keys. With the absent flag it removes all keys listed.

Problem is that I have an old key that is only on the server and I want to remove/overwrite it and for future deployments overwrite any unauthorized keys that might be on the server and not in my playbook.

With the exclusive flag it only takes the last key and adds it. This would be fantastic if it would loop and recusively add all the keys. If there is a way to do this in Ansible I have not found it.

Is there any way to loop over pub files and use the exclusive option at the same time?

Answer

Konstantin Suvorov picture Konstantin Suvorov · Aug 10, 2016

Is there any way to loop over pub files and use the exclusive option at the same time?

No. There is a note about loops and exclusive in the docs:

exclusive: Whether to remove all other non-specified keys from the authorized_keys file. Multiple keys can be specified in a single key string value by separating them by newlines. This option is not loop aware, so if you use with_ , it will be exclusive per iteration of the loop, if you want multiple keys in the file you need to pass them all to key in a single batch as mentioned above.

So you need to join all your keys and send all them at once.
Something like this:

- name: update SSH keys
  authorized_key:
    user: <user>
    key: "{{ lookup('pipe','cat ../files/pub_keys/*.pub') }}"
    state: present
    exclusive: yes

Check this code before running in production!