Easy SSH Access to EC2 Hosts
By Adrian Sutton
We run a bunch of hosts on EC2 and while most just have the default DNS name, they all have a Name tag to identify their purpose. While there’s lots of automation setup via ansible, it is often still necessary to SSH directly into a particular box, especially while debugging issues.
I find it annoying to have to go log into the AWS console just to find the DNS name of the particular box I want so I’ve written a little script that searches for hosts based on the name tag and can then SSH into them.
It requires having the aws
utility setup and able to login, plus having jq
installed.
#!/bin/bash
set -euo pipefail
HOST_NAME=${1:-}
RESPONSE=`aws ec2 describe-instances`
INSTANCES=`jq "[.Reservations[].Instances[]
| select(.State.Code == 16)
| select(.PublicDnsName != \"\")
| select(((.Tags // [])[] | select(.Key == \"Name\")).Value | test(\"$HOST_NAME\"))]
| sort_by((.Tags[] | select(.Key == \"Name\")).Value)" <<< "$RESPONSE"`
HOSTS=(`jq -r '.[].PublicDnsName' <<< "$INSTANCES"`)
HOST_COUNT=${#HOSTS[@]}
if (( $HOST_COUNT == 0 ))
then
echo "No matching hosts"
exit 1
elif (( $HOST_COUNT > 1 ))
then
NAMES=(`jq -r '.[].Tags[] | select(.Key == "Name").Value' <<< "$INSTANCES"`)
echo "Multiple matching hosts found: "
NUM=1
for NAME in ${NAMES[@]}
do
HOSTNAME=${HOSTS[$((NUM - 1))]}
echo "$NUM: $NAME ($HOSTNAME)"
NUM=$((NUM + 1))
done
read -p "Enter the number of the host you meant: " -r SELECTION
SELECTED_HOST=${HOSTS[$((SELECTION - 1))]}
echo "Connecting to $SELECTED_HOST"
ssh $SELECTED_HOST
else
echo "Connecting to ${HOSTS[0]}"
ssh ${HOSTS[0]}
fi
Run with awssh <name>
where <name>
is a regex that matches any Name tag. Typically a substring match is simplest. So to SSH to the Medalla testnet bootnode we run I’d just use awssh medalla-bootnode
.
If more than one node matches it provides a list of the matching nodes, so to select one of the Medalla nodes I’d run awssh medalla
then select from the resulting list.