If you use Ansible to manage servers, you should probably use ssh keys to do so.
Ssh keys are a way of authenticating to a server, like passwords are. Ssh keys
can be protected with passwords or they can be passwordless. If you’re using
them for automation, you might need to use passwordless ssh keys, but otherwise,
it’s a good practice to protect the keys as well.
You can create a key, or really a ssh key pair with the command
ssh-keygen -f <keyfile>
Key files are usually stored in
~/.ssh and their names tend to start with
id_, so the command above could be
ssh-keygen -f ~/.ssh/id_work for your
work computers. It doesn’t cost to create separate key files for separate
contexts, so go wild and create a key pair for your public git project, your
home servers and whatever you care for. For this article though, don’t go
overboard and create a separate key file for each server just yet… until after
reading the article and you know what you’re doing.
A key consists of two parts; a public file and a private file. Like the name
implies, you can freely distribute the public part but you should keep the
private key files strictly to yourself. The files tend to have the same name (by
convention), except that the public file ends in
Now you can distribute (the public half of) your key to the server you want to
log in to with
ssh-copy-id -f <keyfile> <servername>
Then edit the file
~/.ssh/config to list the servers you want your side of the
ssh pipeline to attempt using ssh keys:
Host servername anotherserver *
You can use the
* wildcard where it makes sense. You can also say
User <username> under the Host line if your username on the remote server is
different from the one on your computer.
For a seasoned systems administrator, this should be nothing new. So let’s up
If you value security and/or there are several of you who share the joy of
configuring servers, you might want a key for logging in as yourself to servers
as a normal part of your work, and a separate key to use for Ansible work. You
might even administer servers under a different username than your normal login
name. This might be especially true if several of you share the server admin
duties (though from a security perspective, it’s even better if you do so using
Let’s assume the ansible work is done using the unimaginatively named user
ssh-key -f ~/.ssh/id_ansible
ssh-copy-id ~/.ssh/id_ansible ansible@<servername>
(In a perfect environment where chicken and eggs evolve in parallel, you
distribute ssh keys using key management or Ansible itself, and never log in
to servers as that ansible user, but that’s for a post somewhere else.)
As a friend of security, you did add passwords to your ssh keys, right? If not,
create new ones with passwords. This post will wait.
You now need the
ssh-agent. Ssh-agent will cache the passwords you created
above so that you don’t need to enter them by hand, for example when running
Ansible jobs. Check that it’s running by running
ssh-agent. Then to add
passwords to the agent, use
If you’re really lazy, just say
ssh-add ~/.ssh/* to add all of your keys.
ssh-agent will prompt for the passwords and remember them until you log out or
ssh keys and Ansible
Finally, to the beef: using a different ssh key and a different username for
ansible than for regular ssh. You’d think that you can add this configuration to
ansible.cfg file, but alas you’d be wrong (don’t worry, i was too, and i
still think both of us should be right). The ssh username and key file
configuration belongs to variables that relate to the servers you connect to.
There are two places you might add these to: the
inventory or your
As a well structured admin, you probably have all your inventory in an
inventory/ directory and not a flat file. Create a file there, say
inventory/ssh.config which says something along the lines of
inventory/ssh.config will look, smell and sound like an inventory
file, but in fact, it’s just a variable declaration to all your targets. Of
course, edit as necessary; you might have machines that you don’t use those
usernames and key files to acces. This is but a simplified example.
You can also use your
group_vars files for this. The corresponding
configuration for above would be
The benefit of using
*_vars files is that you can have cascading
configuration, so that you can have a different username for your bone headed
switch which thinks the username must be
admin, or different ssh key files for
some reason or another.
So yeah, that’s what i learned this week. Using dedicated keys for Ansible.