Better handling of public SSH keys using Ansible..

Ansible has a dedicated module to manage public keys; the authorized_key module. It’s a very nice module, with enough flexibility to do almost anything I can think of.

However, it does have one very annoying thing. While I was migrating our automation scripts to ansible; I got to the point where I was working on the script that provisions our users. By default, we disabled all password authentication and root SSH access. Only key based access is allowed.

I found that I have to actually put the public SSH key strings inside the playbook vars. That’s just not cool. SSH keys are long, they might have specific options (although the authorized_key module allows you to configure that) and it’s harder to maintain the list of keys like this. So, I tried to work around this. My target was to add the public SSH keys for my users as static files in an ansible role. Basically, I will be populating my my group_vars files by reading files inside my roles.

  • First, I added the public key files in the ‘files‘ directory of the role I was using to configure the users.
  • Now, I have to find a way to “read” the key files and set them in the vars file. Fortunately, ansible provides Lookup plugins that allows me to do just that!
  • So, the related part of the vars file should look like this:


ssh_users:
  - name: user1
    key: "{{ lookup('file', 'user1.pub') }}"
  - name: user2
    key: "{{ lookup('file', 'user2.pub') }}"
  - name: user3
    key: "{{ lookup('file', 'user3.pub') }}"
  - name: user4
    key: "{{ lookup('file', 'user4.pub') }}"

  • Next, all we need to do is call the authorized_key module as usual

- name: Add ssh user keys
  authorized_key: user={{ item.name }} key="{{ item.key }}"
  with_items: ssh_users

Edit: Updated the variable name to avoid the deprecated syntax. Details in the first comment.

Here you go. Key files are neatly tucked in the files directory, easy to maintain and no wrapped lines and cluttered options missing up your var files.