I'm an intensive user of AWS EC2 instances, many instances are launched, stopped, repurposed, etc.
To connect to any instance using SSH
I must keep track of their IPs.
The bash script I wrote (following the question I asked on SO) uses aws-cli
to do the heavy lifting for me, leaving me to remember only the logical names I've given to my instances.
Here is the main code, including the auto-completion code:
# connect to machine
function sash {
if [ -z $1 ]; then
echo "Please enter machine name"
return 1
fi
local instance ip pem
instance=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=$1" "Name=instance-state-name,Values=running" --query 'Reservations[*].Instances[].[KeyName,PublicIpAddress]' --output text)
if [ -z "${instance}" ]; then
echo Could not find an instance named $1
return 1
else
ip=$(echo $instance | awk '{print $2}')
pem=$(echo $instance | awk '{print $1}')
echo "Connecting to $1 ($ip)"
ssh -i ~/.aws/$pem.pem ubuntu@$ip
fi
}
function clear_sash {
unset -v _sash_instances
}
# completion command
function _sash {
if [ -z "${_sash_instances}" ]; then
_sash_instances="$( aws ec2 describe-tags --filter Name=key,Values=Name Name=resource-type,Values=instance --query Tags[].Value --output text )"
fi
local curw
COMPREPLY=()
curw=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=($(compgen -W "${_sash_instances}" -- $curw))
return 0
}
complete -F _sash sash
The main function (sash
) takes the first parameter, and queries aws ec2
for a machine with a 'Name' tag with that value, extracts its public ip and pem
file, and calls the proper ssh
command.
The auto-completion command (_sash
) enumerates the names of all EC2 machines, and keeps them in a cache in the scope of the shell.
A small helper command (clear_sash
) is used to clear the cache for the auto-complete.
Since this is the first function I've written in bash, I would love to hear some opinions on the code, style, caching decisions, etc.