SSH into private ec2-instances

Published on May 18, 2020 By Xander Verheij — Infrastructure as code


Premise

Theoretically you start you deploy your elasticbeanstalk using your terraform infrastructure code and everything works out of the box. But more often then not, something doesn’t go as planned; and to speed up the debugging it would be really helpfull to just ssh into the underlying ec2-instance.

However that ec2-instance is running in a private subnet, thus not accessible via the internet. First solution that comes to mind is setting up a bastion server, but with AWS ssm we have a different option.

Again thanks to my colleague Joep Joosten for doing the heavy lifting.

Prerequisites

  • AWS Session Manager plugin check here for install guide
  • To easily access instances from a suborganization check this blogpost

Install ssh over ssm

Install the library that makes the magic happen, all credits go to elpy1!

git clone https://github.com/elpy1/ssh-over-ssm.git ~/ssh-over-ssm

Configure ssh

Add the following to your ~/.ssh/config. Make sure to check the ProxyCommand it should point to ssh-over-ssm you just cloned from github.

Match host i-*
StrictHostKeyChecking no
IdentityFile ~/.ssh/ssm-ssh-tmp
PasswordAuthentication no
GSSAPIAuthentication no
ProxyCommand ~/ssh-over-ssm/ssh-ssm.sh %h %r

Optional configure aws to use suborganization using aws-mfa

aws-mfa {suborganization} {mfa_code}

Find the instance you want to connect to

The following command can be used to find all the instances running in the account you have access to

aws ec2 describe-instances --query "Reservations[*].Instances[*].{name: Tags[?Key=='Name'] | [0].Value, instance_id: InstanceId, ip_address: PrivateIpAddress, state: State.Name}"  --output table

To make it a little bit easier you can add it to your .zshrc, .bashrc, [othershell]rc

alias listec2="aws ec2 describe-instances --query \"Reservations[*].Instances[*].{name: Tags[?Key=='Name'] | [0].Value, instance_id: InstanceId, ip_address: PrivateIpAddress, state: State.Name}\"  --output table"

Connect using ssh!

Simply connect to the instance you want by using the following command:

ssh ec2-user@i-xyz123456789

And check whichever log you want, or use your tool of choice to check if you can connect to where you want to connect :-)