Skip to content

Instantly share code, notes, and snippets.

@t27
Created May 6, 2021 04:01
Show Gist options
  • Save t27/7445f87f0f3e98ad8f6cdf3102724f41 to your computer and use it in GitHub Desktop.
Save t27/7445f87f0f3e98ad8f6cdf3102724f41 to your computer and use it in GitHub Desktop.
Regularly Terminate AWS instances that are idle(<5% CPU Utilization) for the past 10 minutes
import json
import subprocess
import pendulum # pip install pendulum
# Note: This is a hacky, quick solution prototyped in less than an hour, the ideal solution would involve using boto3 and other best practices auth
# ensure that your AWS CLI is configured and has the keys and default region set up. This script works in the default region
instance_cmd = """
aws ec2 describe-instances \
--filters "Name=tag-key,Values=Name" "Name=instance-state-name,Values=running"\
--query 'Reservations[*].Instances[*].{Instance:InstanceId,AZ:Placement.AvailabilityZone,Name:Tags[?Key==`Name`]|[0].Value}' \
--output json
"""
instances = subprocess.check_output(instance_cmd, shell=True)
try:
instances = json.loads(instances)
except:
print(instances)
exit()
ids = [k[0]["Instance"] for k in instances]
endtime = pendulum.now().utcnow()
starttime = endtime.subtract(minutes=10)
idle_instances = []
print(pendulum.now().to_datetime_string())
print("----------------------------------------------------------------")
for id in ids:
cloudwatch_cmd = f"""aws cloudwatch get-metric-statistics --namespace AWS/EC2 --metric-name CPUUtilization --period 3600 \
--statistics Average --dimensions Name=InstanceId,Value={id} --start-time {starttime.to_iso8601_string()} --end-time {endtime.to_iso8601_string()} \
--output json
"""
res = subprocess.check_output(cloudwatch_cmd, shell=True)
res = json.loads(res)
avg_util = res["Datapoints"][0]["Average"]
print(id, avg_util)
if avg_util < 5:
idle_instances.append(id)
if len(idle_instances) > 0:
print(idle_instances)
terminate_cmd = f"aws ec2 terminate-instances --instance-ids {' '.join(idle_instances)} --output text"
print(terminate_cmd)
print(str(subprocess.check_output(terminate_cmd, shell=True)))
print(f"Terminated {len(idle_instances)}")
print("----------------------------------------------------------------")
# Example CRON Tab command to run this script regularly (the below command runs this script every 15 mins)
# */15 * * * * python /home/ubuntu/aws_terminator.py >> ~/aws_terminator.log
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment