Management of multiple exclusive authorized_keys entries, for multiple users

Hi everyone.

I’ve been mulling something over in my head, I’ve got something I want to tackle, but I’m not sure how to go about doing so.

Here’s the scenario: I want to put together a tiny role that manages user’s authorized keys. Keys defined in the inventory (host_vars/group_vars/playbook vars, etc.) should be the only ones present in the user’s authorized_keys file.

I have some keys specified like so:

`

root_ssh_public_keys:
  member1:
    pubkey: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvVO3ULx8fNGgInHCFQV6w/gEARBWyS9eA1qRaTEu4njawEjiqSGFHgPuvmgtKlft2MqbnCG3cokFKRAEOZEzy+jUMES8IQEHuSsJuZFnlUC4yzm1mI1OjJk9PwTLDD6OGJDL1gIkz37CYITbsaufS6gFrpoMBZhkVcVKk0JBnmwF/QZUD1uHKFLMtyVwvw8pzWcBcAYBBw5O6hjo2pRIX100bCdMxDrXwFp4yFiJPG6LCya4701whZpqgwk3d/RakJdZLA3pgAlVPZswz8ezj2U5PIYJl+LrUaPE57ZR/eVwNnBE7QPsKCCurIy1bLR0KXiqOmUzdzWDphYCelRurQ== member1
  member2:
    pubkey: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtkScC/o1aDxaXFJdyTMhlF4UewNO/tdQf6EIYJzikSBNKECBjmvrM6bNaIkWA/AzB2dgTS0mug2aVomsBeyN8gAGfV/Wi3bO1kXuI23BmkPUn36OgE5ppQ0O2Gp8VjJaffV9EiYeEY/QlwnshAS9gfDPeTO+u5f0ZP0TZw29m+F3CKIJWPruDJJvXMkyc5qokh5kUpm0qYlhGyDi596st3Gsh/9LF/I2sEJH3LTP0gs0bWjbHN9XcIw8gbPT50zNZvqv9FGvgsMCErYC5lwPVN1670cpOpqLYV4PgU77t751CE9RsmASeB6Elwh0pAKlfxzITBx4W6aVxkl8Utlblw== member2
  member3:
    pubkey: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA2nyE+baFvebdFqiuEEjGYtLHxgduypfBg1laG8DP9Re0ln0lIJRsTw2HoB1giKRpkLXUdYkS+QVkzP0oZCNRZWuEgIuJnL8vl6c0S53UaFTNbZliIuSQLSPsEbQfIu1lQ9voZG2pwJQTj4yICnr29dSPs6ef4n8pox7hhDZSf6LBrrWWc51WYrZwXCSeDstqq53goCKLeujSZ6Ww3T7Ac17OzyhIQCl0x1w8LlcMshaczPKbFLxgLltIF8OmX9PLHuX0enFOVGKyRW66MIIyHuK65gxY/+8mjrzTw9aWOiQVvYZsjuzqBIBQy4h85ex8wF0xztR50D2ylvrbXSNl2w== member3

`

Currently, I have this task that deploys them and ensures they’re the only keys in the root user’s authorized_keys list:

`

  • name: “Ensure team pubkeys are in root’s authorized_keys”
    authorized_key:
    user: root
    manage_dir: yes
    exclusive: yes
    key: |
    {% for _, user in root_ssh_public_keys.items()%}
    {% for _, key in user.items() %}
    {{ key }}
    {% endfor %}
    {% endfor %}
    tags: ssh_keys

`

Now, what I want to be able to do is chuck this into a little role, and have it be usable for any user definitions.
So, say I had a system with the user ‘example’ on, and I wanted to specify some keys I want that user to have in their authorized_keys list.
I could go to that system’s host_vars and add the following:

`

`

example_ssh_public_keys:
  someone:
    pubkey: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvVO3ULx8fNGgInHCFQV6w/gEARBWyS9eA1qRaTEu4njawEjiqSGFHgPuvmgtKlft2MqbnCG3cokFKRAEOZEzy+jUMES8IQEHuSsJuZFnlUC4yzm1mI1OjJk9PwTLDD6OGJDL1gIkz37CYITbsaufS6gFrpoMBZhkVcVKk0JBnmwF/QZUD1uHKFLMtyVwvw8pzWcBcAYBBw5O6hjo2pRIX100bCdMxDrXwFp4yFiJPG6LCya4701whZpqgwk3d/RakJdZLA3pgAlVPZswz8ezj2U5PIYJl+LrUaPE57ZR/eVwNnBE7QPsKCCurIy1bLR0KXiqOmUzdzWDphYCelRurQ== someone
  someone_else:
    pubkey: ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAtkScC/o1aDxaXFJdyTMhlF4UewNO/tdQf6EIYJzikSBNKECBjmvrM6bNaIkWA/AzB2dgTS0mug2aVomsBeyN8gAGfV/Wi3bO1kXuI23BmkPUn36OgE5ppQ0O2Gp8VjJaffV9EiYeEY/QlwnshAS9gfDPeTO+u5f0ZP0TZw29m+F3CKIJWPruDJJvXMkyc5qokh5kUpm0qYlhGyDi596st3Gsh/9LF/I2sEJH3LTP0gs0bWjbHN9XcIw8gbPT50zNZvqv9FGvgsMCErYC5lwPVN1670cpOpqLYV4PgU77t751CE9RsmASeB6Elwh0pAKlfxzITBx4W6aVxkl8Utlblw== someone_else  

`

`

Notice the variable name is ‘example_ssh_public_keys’.
In my task above, I need a way of dynamically defining both the ‘user’ parameter value (shown above as ‘root’) and the dictionary I’m operating on (shown above as ‘root_ssh_public_keys’).

My point being I need this to be re-usable for different users.

Am I going about this in a really stupid manner? What would be the best way to approach this?

Thanks in advance for any help!

Right of the top of my head, put user specific stuff in a dict in vars file (or conditional include a file for each user), so you have a dict that’s populated differently based on the value of a “user” var.

Then in a dependencies section in a meta/main.yaml, you just do
{ role: sshrolename, user: username }
{ role: sshrolename. user: otherusername }

Of course that’s gonna be slow, so you could write your role to want a list of users, and then pass a list in the meta/main.yaml file. You can always pass a list with one item.

Hi,

I am using the assemble module, like this:

- name: ssh keys for root
  assemble: src=. dest=/root/.ssh/authorized_keys owner=root group=root mode=0600 remote_src=false

This ensures a synced set of SSH keys from a dir in my playbook repo, where all stale keys are being removed and all modifications are detected. This makes use of the fact that SSH accepts multiple keys in a single file.

Best regards,
Daniel