This PR brings in playbooks/ssh-keys.yml to our ansible scripts. This play looks for two vars in the given inventory files (or passed in as runtime variables): approved_users and removed_users.
Both variables are lists of github users. approved_users is required to run the play (it will fail if it doesn't find it, or if it isn't given as a list). removed_users is optional. For each approved user, we ensure their keys (at https://github.com/{{user}}.keys) exists on the remote host, using ansible's builtin authorized_key role.
If removed_users exists, then we loop through them and ensure their keys are not on the host, using the same builtin.
I deliberated on this, trying to find the most declarative way to set the list of users that should be on a server, while making the play safe and simple to run. I wanted to use ansible builtins instead of some custom script (e.g. editing or replacing the authorized_keys), to avoid a situation where we could accidentally lock ourselves out of the server due to incorrect string manipulation or what-have-you. the authorized_key builtin only allows you to add or remove keys, with the option of the exclusive attribute to say "add only this key". That exclusive doesn't work on a loop though, as it just means the last user in the loop would be the only one who could access it. So I was working on some superuser who gets added exclusively first(e.g. me, so I don't get locked out) and then loop through the list of approved_users and add them. This had the benefit of not having to keep a second list of removed users, but it was also clanky and dangerous.
So I compromised with the two lists, where you can define them at the inventory level and set different users for different groups of servers. It still is declarative, and we keep a history of people who formerly had keys but no longer, and is safe. The downside is we must remember when someone is offboarded and add them to the list.
I tested this script on our dev servers and then ran it for all pubs and all nos services, removing boreq from the servers and adding dcadenas where relevant.
This PR brings in
playbooks/ssh-keys.yml
to our ansible scripts. This play looks for two vars in the given inventory files (or passed in as runtime variables): approved_users and removed_users.Both variables are lists of github users.
approved_users
is required to run the play (it will fail if it doesn't find it, or if it isn't given as a list).removed_users
is optional. For each approved user, we ensure their keys (at https://github.com/{{user}}.keys) exists on the remote host, using ansible's builtinauthorized_key
role.If
removed_users
exists, then we loop through them and ensure their keys are not on the host, using the same builtin.I deliberated on this, trying to find the most declarative way to set the list of users that should be on a server, while making the play safe and simple to run. I wanted to use ansible builtins instead of some custom script (e.g. editing or replacing the authorized_keys), to avoid a situation where we could accidentally lock ourselves out of the server due to incorrect string manipulation or what-have-you. the authorized_key builtin only allows you to add or remove keys, with the option of the
exclusive
attribute to say "add only this key". That exclusive doesn't work on a loop though, as it just means the last user in the loop would be the only one who could access it. So I was working on some superuser who gets added exclusively first(e.g. me, so I don't get locked out) and then loop through the list of approved_users and add them. This had the benefit of not having to keep a second list of removed users, but it was also clanky and dangerous.So I compromised with the two lists, where you can define them at the inventory level and set different users for different groups of servers. It still is declarative, and we keep a history of people who formerly had keys but no longer, and is safe. The downside is we must remember when someone is offboarded and add them to the list.
I tested this script on our dev servers and then ran it for all pubs and all nos services, removing boreq from the servers and adding dcadenas where relevant.