Currently I work at Buzzstarter Inc., and I’ve been working on the web app, which infrastructure is hosted in Amazon Web Services. In general, we don’t really need to SSH into EC2 instances because the deployment pipeline is fully automated with OpsWorks, but in many cases it’s still useful to quickly jump into servers console. Here are some reasons you might want to do that:

  • Check application health in detail when information provided by other services such as NewRelic, AirBrake, CloudWatch, Rollbar were not enough
  • Perform Quality Assurance at system-level. E.g.: QA deployment changes that cause system packages to be updated
  • Verify responsiveness of a particular server

The problem

Our environments are very dynamic - we often make changes in our servers configuration and sometimes, due to unexpected issues, we have to shutdown or spin up a new EC2 instance, so our servers are constantly changing IP addresses. A while ago, I used to keep my SSH config (~/.ssh/config) with a mapping of server names with their IP addresses, but I was getting tired of updating that file due to constant changes.

You probably heard about AWS-CLI - a tool that allows you to interact with Amazon infrastucture via command-line. Unfortunately, there’s really no easy way to make use of that to get access via SSH to your instances.

For a while I was really dreaming of being able to SSH to any EC2 instance with just a friendly name in hand. It would be also pretty cool to list the instances per Stack (configured in OpsWorks), so that I could quickly jump into every server of one environment - let’s say I want to SSH into servers of Staging environment.

The solution

Yesteday I launched AWS-SSH - it’s a simple tool that made my dream come true. I think it’s a lot easier to show how useful is that by showing examples, so check out below how to setup and use it.

Setting up the tool

NOTE: the CLI can be run through both aws-ssh and awssh.

  1. Make sure you have aws-cli installed and configured. Follow guide in https://github.com/aws/aws-cli

  2. Install aws-ssh gem: gem install aws-ssh

  3. Create a file named .awssh with default options:

```
profile: your-app-aws-cli-profile-name
region: us-east-1
user: custom-machine-user-for-ssh
```

Examples

  1. List servers filtered by name staging. Here we use option -so, which is the short of --show-only, i.e., it will list only, and not try to SSH.
```
$ awssh -so staging
ssh user@10.20.30.40 => Buzzstarter Staging - staging-app
ssh user@10.20.30.41 => Buzzstarter Staging - staging-worker

# All hosts in one-line (suitable for CSSH):
user@10.20.30.40 user@10.20.30.41
```
  1. SSH into first production app server. Here we use regex to filter server hostname.
```
$ awssh prod.*app1
user@prod-rails-app1:~$ # you can now interact with this server from now on
```
  1. In first example, you can observe the last line of the output contains a whitespace-separated list of servers. We can use that as an input to a Cluster-SSH tool in order to SSH into multiple servers at once. I’m gonna use tmux-cssh for example:
```
$ tmux-cssh $(awssh -so prod.*app | tail -1)
```

The result is:

![](/assets/images/tmux-cssh.png)
  1. If you are user of OpsWorks, you can also filter by Stack name: The -s is the short of --stack, which value is a regex:
```
$ awssh -so -s qa
ssh user@10.20.40.40 => Buzzstarter QA - testing-app
ssh user@10.20.40.41 => Buzzstarter QA - testing-worker

# All hosts in one-line (suitable for CSSH):
user@10.20.40.40 user@10.20.40.41
```

More information: https://github.com/buzzstarter/aws-ssh

Contributions are welcome!

Happy coding, folks!