Skip to content

Instantly share code, notes, and snippets.

@pifalken
Last active June 8, 2020 18:51
Show Gist options
  • Save pifalken/96848b53227d0237613db14db2b455fe to your computer and use it in GitHub Desktop.
Save pifalken/96848b53227d0237613db14db2b455fe to your computer and use it in GitHub Desktop.
small aws bash script to make a couple of things faster
#!/usr/bin/env bash
# welcome to terraform 2.
# warning to all ye who enter here
# this is fucked lol and may not work all the time
# i'm writing this tool cause i really can't be fucked to memorize all of AWS's
# arcane cli syntax -- although i'm probably doing the /exact oppopsite/
set -e
set -o errexit # exit on error
set -o errtrace # exit on error inside funcs
set -o nounset # no undefined vars
set -o pipefail # use last non-zero exit code in pipeline
#set -o xtrace # debug trace
function get_allinstances() {
echo "getting instances in ${fg_cyan}$1${ta_none}"
# @note: fyi, you can also do shit like:
# aws ec2 describe-instances --region eu-west-2 --instance-ids $id --query "Reservations[*].Instances[*].Tags[*].{Name:Value}"
# https://docs.aws.amazon.com/cli/latest/reference/ec2/describe-instances.html
instance_names=($(aws ec2 describe-instances --region $1 | awk '/Key": "Name"/{getline; print}' | sed 's/[ \t]\?//g' | awk 'BEGIN {FS=":"} {print $2}' | sed 's/"//g')) # dangerous :(
instance_ids=($(aws ec2 describe-instances --region $1 | grep 'InstanceId": "i-' | sed 's/[ \t]\?//g' | awk 'BEGIN {FS=":"} {print $2}' | sed 's/"//g' | sed 's/,//g'))
live_status=($(aws ec2 describe-instances --region $1 | awk '/State": {/{nr[NR + 2]}; NR in nr' | awk 'BEGIN {FS=":"} {print $2}' | sed 's/[ "]//g')) # ooooof
printf "found ${fg_green}${#instance_names[@]}${ta_none} instances:\n"
#printf "%s\n" "${instance_names[@]}"
for i in "${!instance_names[@]}"; do
if [ "${live_status[$i]}" == "running" ]; then c=$fg_green; else c=$fg_red; fi
printf "%s %s %s\n" "$(($i + 1)). [${c}${instance_names[$i]}${ta_none}: ${instance_ids[$i]}]"
done
}
function _get_instance() {
if [[ $2 == i-* ]]; then
local name=$(aws ec2 describe-instances --region $1 --instance-id $2 | awk '/Key": "Name"/{getline; print}' | sed 's/[ \t]\?//g' | awk 'BEGIN {FS=":"} {print $2}' | sed 's/"//g')
echo "$name"
else
local id=$(aws ec2 describe-instances --region $1 --filters Name=tag:Name,Values=$2 --query "Reservations[*].Instances[*].{Instance:InstanceId}" --output text) # fancy aws-cli syntax for you non-bash noobs
echo "$id"
fi
}
function instance_info() {
if [[ $2 = 'i-'* ]]; then
iname=$(_get_instance $1 $2)
id=$2
else
iname=$2
id=$(_get_instance $1 $2)
fi
instance_ip=$(aws ec2 describe-instances --region $1 | grep $id -B 8 -C 16 | grep PublicDnsName | sed 's/[ \t]\?//g' | awk 'BEGIN {FS=":"} {print $2}' | sed 's/[",]//g')
echo "instance info:"
printf "[$iname/$id] pub dnsname: ${fg_cyan}$instance_ip${ta_none}\n"
}
# @note: "this works on my machine" LOL
function ssh_connect() {
echo -e "\ni won't ssh in for you, but i'll give you the command"
echo "checking if SSH key exists..."
keyname=$(aws ec2 describe-instances --region $1 --instance-id $2 --query "Reservations[*].Instances[*].{Name:KeyName}" --output text)
if [ -f $HOME/.ssh/$keyname.pem ]; then
read -p "username: " -r
else
printf "key [$keyname] ${fg_red}not found${ta_none}!\n"
exit 0
fi
printf "${fg_yellow}ssh -i $HOME/.ssh/$keyname.pem $REPLY@$instance_ip${ta_none}\n"
}
function start_instance() {
#region="$1" shift;
# ...
params=("$@")
if [[ ${#params[@]} != 2 ]]; then echo "not enough parameters"; help_adv; fi
region=${params[0]}
instance=${params[1]}
if [[ $instance = 'i-'* ]]; then
iname=$(_get_instance $region $instance)
id=$instance
else
iname=$instance
id=$(_get_instance $region $instance)
fi
printf "${fg_green}starting instance id: $2 [$iname/$id]${ta_none}\n"
aws ec2 start-instances --region $region --instance-id $id
infomsg="waiting for instance to boot up and have IP assigned... "
_spinner "$infomsg"
instance_ip=$(aws ec2 describe-instances --region $region | grep $id -B 8 -C 16 | grep PublicDnsName | sed 's/[ \t]\?//g' | awk 'BEGIN {FS=":"} {print $2}' | sed 's/[",]//g')
printf "\ninstance ip: ${fg_cyan} $instance_ip${ta_none}\n"
echo "done."
read -p "would you like to ssh in? [y/n]: " -n 1 -r
if [[ $REPLY =~ ^[Yy]$ ]]; then
ssh_connect $region $id $instance_ip
fi
}
function stop_instance() {
#region="$1" shift;
# ...
params=("$@")
if [[ ${#params[@]} != 2 ]]; then echo "not enough parameters"; help_adv; fi
region=${params[0]}
instance=${params[1]}
if [[ $instance = 'i-'* ]]; then
iname=$(_get_instance $region $instance)
id=$instance
else
iname=$instance
id=$(_get_instance $region $instance)
fi
printf "${fg_red}stopping instance id: $2 [$iname/$id]${ta_none}\n"
aws ec2 stop-instances --region $region --instance-id $id
echo "done."
}
function help_basic {
echo "usage: $(basename $0) <command> [options]"
echo "to see help text, run $(basename $0) with -h or --help"
}
function help_adv {
cat << EOF
usage:
-s, --start "<region> <instance>" starts instance X in <region>
ex: -s "eu-west-2 i-1234a5b6789c", -s "eu-west-2 secretbox"
-d, --stop "<region> <instance>" stops instance X in <region>
ex: -d "eu-west-2 i-1234a5b6789c", -d "eu-west-2 secretbox"
-n, --getinstances <region> gets all instances in <region> and returns names and ids
-i "<region> <instance>" show info about instance id
-h, --help displays this help
EOF
exit 0
}
# @todo: add long opt names --start etc.
# @todo: support multiple arguements without using ""
function usage_main() {
local opt
while getopts "i:n:s:d:kh" opt; do
case $opt in
n)
region=$OPTARG
get_allinstances $region
exit 0
;;
i)
params=$OPTARG
instance_info $params
exit 0
;;
s)
params=$OPTARG
start_instance $params
;;
d)
params=$OPTARG
stop_instance $params
exit 0
;;
h)
help_adv
exit 0
;;
*)
echo "invalid params were provided"
exit 0
;;
esac
done
}
function _spinner() {
spinstr='|/-\'
reset="\b\b\b\b" # len $spinstr
for i in {0..150}; do # 15s / 0.1 sleep
tmp=${spinstr#?}
printf "$1 %c" "$spinstr"
spinstr=$tmp${spinstr%"$tmp"}
sleep 0.1
for ((j=1; j<=$(echo $1 | wc -c); j++)); do
reset+="\b"
done
printf "$reset"
done
printf "\t\b\b\b\b"
}
function _color_init() {
readonly ta_none="$(tput sgr0 2> /dev/null || true)"
if [[ -z ${no_color-} ]]; then
readonly ta_bold="$(tput bold 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly ta_uscore="$(tput smul 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly ta_blink="$(tput blink 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly ta_reverse="$(tput rev 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly ta_conceal="$(tput invis 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly fg_black="$(tput setaf 0 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly fg_blue="$(tput setaf 4 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly fg_cyan="$(tput setaf 6 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly fg_green="$(tput setaf 2 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly fg_magenta="$(tput setaf 5 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly fg_red="$(tput setaf 1 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly fg_white="$(tput setaf 7 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly fg_yellow="$(tput setaf 3 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly bg_black="$(tput setab 0 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly bg_blue="$(tput setab 4 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly bg_cyan="$(tput setab 6 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly bg_green="$(tput setab 2 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly bg_magenta="$(tput setab 5 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly bg_red="$(tput setab 1 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly bg_white="$(tput setab 7 2> /dev/null || true)"
printf '%b' "$ta_none"
readonly bg_yellow="$(tput setab 3 2> /dev/null || true)"
printf '%b' "$ta_none"
fi
}
function main() {
if [[ $# -eq 0 ]]; then
help_basic
exit 0
fi
_color_init
usage_main "$@"
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment