As anybody who deals with multiple servers in multiple AWS accounts knows, it can be a real pain to maintain an up-to-date ~/.ssh/config
file. Most solutions I've found for managing this assume you only have one AWS account. I've decided to share my setup for how I deal with managing my ssh config file that contains entries from 4 different AWS accounts, two Linode accounts, and some other random entries.
If you want to cut to the chase, you can check out this project on Github.
Folder structure:
. ├── aws │ ├── geoloqi.profile │ ├── geotrigger.profile │ ├── geotrigger-dev.profile │ └── esripdx.profile ├── ssh │ ├── _base.sshconfig │ ├── esripdx.sshconfig │ ├── geoloqi.sshconfig │ ├── geotrigger.sshconfig │ ├── geotrigger-dev.sshconfig │ └── personal.sshconfig ├── bash-complete.sh ├── rebuild-ssh-config.sh └── ssh-servers-from-aws.rb
The "aws" folder contains my AWS API key/secrets for each AWS account. For example:
export AWS_ACCESS_KEY=XXXXXXXXX export AWS_SECRET_KEY=XXXXXXXXX
(The reason I have "export" in there is so that I can source this file from bash, allowing me to also use the same set of files with the Amazon command line utils, switching accounts by sourcing each different file)
The "ssh" folder contains the generated and hand-edited ssh config files. I created a _base.sshconfig
file where I put global config data, such as:
Host * ServerAliveInterval 60 ForwardAgent yes IdentitiesOnly yes
My personal.sshconfig
file is a hand-edited file where I put a list of some of my Linodes and home servers. The other files are auto-generated by querying each AWS account for their list of servers.
Setup
- Create a file in the "aws" folder to store your AWS credentials, one file per AWS account
- In your AWS account, ensure each server has a unique name, and add a "User" tag if the SSH username is different from "ubuntu"
- Add your existing .ssh/config contents into a file in the "ssh" folder to save any settings or other servers you have there
- Run
bundle install
to install the necessary gems - Source the
bash-complete.sh
file from your.bash_profile
to enable autocomplete - Ensure you have the corresponding SSH private key in your
~/.ssh
folder that matches with the key listed on each EC2
Usage
To generate the ssh config file for an AWS account, run:
bundle exec ./ssh-servers-from-aws.rb example
Replace "example" with the name of your AWS profile. This will query your AWS account for all running servers, adding each to a file in the "ssh" folder. The following information will be pulled from each EC2:
- The "Name" tag is used as the server alias in the config file
- The "User" tag sets the SSH username (defaults to "ubuntu" if not present
- The SSH private key file referenced in the EC2 is used as the "IdentityFile" config option
- The IP address of the EC2 is used for the "HostName" option (to avoid DNS issues)
After you generate the ssh configs for each AWS account, you'll need to update your master ~/.ssh/config
file.
Run rebuild-ssh-config.sh
, which combines all your ssh/*.sshconfig
files into the master ~/.ssh/config
file. Note that your previous ~/.ssh/config
file will be overwritten, so make sure you move any important things into the "ssh" folder before you do so.
Tab-Complete!
Now you are ready to go! You can do things like:
$ ssh e[TAB]
auto-expands to $ ssh example
Or if you have multiple servers with the same prefix,
$ ssh e[TAB][TAB] example-1 example-2
If you name your servers with common prefixes per account, or by prefixing types of machines with the same prefix (worker-* vs db-* for example) then the tab-complete becomes even more useful!