Skip to content

Instantly share code, notes, and snippets.

@dmc5179
Created April 21, 2020 13:31
Show Gist options
  • Save dmc5179/4189f665d64338dd5813ef578099549a to your computer and use it in GitHub Desktop.
Save dmc5179/4189f665d64338dd5813ef578099549a to your computer and use it in GitHub Desktop.
Locate AWS EC2 instances that have been stopped for more than a defined number of days
#!/bin/bash
# Locate stale AWS EC2 Instances
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
function show_help() {
echo "$0: -s <running|stopped> -p <aws-cli-profile> -a <max-age> -r <aws-region> -v"
}
OPTIND=1 # Reset in case getopts has been used previously in the shell.
# Initialize our own variables:
OWNER=""
VERBOSE=0
PROFILE="default"
REGION="us-east-1"
MAX_AGE=30
MAX_DATE=$(date --date "today -${MAX_AGE} day" +%Y-%m-%d)
while getopts "h?vo:r:p:s:a:" opt; do
case "$opt" in
h|\?)
show_help
exit 0
;;
v) VERBOSE=1
;;
o) OWNER="--owner-ids ${OPTARG}"
;;
s) STATE=$OPTARG
;;
r) REGION=$OPTARG
;;
p) PROFILE=$OPTARG
;;
a) MAX_AGE=$OPTARG
MAX_DATE=$(date --date "today -${MAX_AGE} day" +%Y-%m-%d)
;;
esac
done
shift $((OPTIND-1))
[ "${1:-}" = "--" ] && shift
INSTANCES="/tmp/instances.txt"
aws --profile ${PROFILE} --region ${REGION} ec2 describe-instances \
--filters Name=instance-state-name,Values=${STATE} --output text \
--query 'Reservations[*].Instances[*].InstanceId' > ${INSTANCES}
if [[ ${VERBOSE} == 1 ]]
then
INSTANCECOUNT=$(grep -o 'i\-' ${INSTANCES} | wc -l)
echo "Scanning ${INSTANCECOUNT} instances"
fi
for instance in $(cat ${INSTANCES})
do
if [[ ${VERBOSE} == 1 ]]
then
echo "Checking: $instance"
fi
STR=$(aws --profile ${PROFILE} --region ${REGION} ec2 describe-instances --instance-ids ${instance} --output text --query 'Reservations[*].Instances[*].StateTransitionReason')
# Not all stopped instances contain the time they were stopped
if [[ "${STR}" =~ .*"GMT".* ]]
then
TEMP="$(echo ${STR} | sed 's/User initiated //' | tr -d '\(' | tr -d '\)')"
STOPPED_DATE=$(date --date "${TEMP}" +%Y-%m-%d)
if [[ ${STOPPED_DATE} < ${MAX_DATE} ]]
then
echo "Instance: ${instance} has been stopped for more than ${MAX_AGE} days"
fi
fi
done
rm -f ${INSTANCES}
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment