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.
. ├── 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
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.
- 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
bundle installto install the necessary gems
- Source the
bash-complete.shfile from your
.bash_profileto enable autocomplete
- Ensure you have the corresponding SSH private key in your
~/.sshfolder that matches with the key listed on each EC2
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
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.
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!