Skip to content

Instantly share code, notes, and snippets.

@BenHigginbottom
Created February 9, 2017 23:57
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save BenHigginbottom/d4b0e3ea9c807187315257d195f2c3b4 to your computer and use it in GitHub Desktop.
Save BenHigginbottom/d4b0e3ea9c807187315257d195f2c3b4 to your computer and use it in GitHub Desktop.
#Nicked from http://blog.ranman.org/cleaning-up-aws-with-boto3/
import boto3
from datetime import datetime, timedelta
region = "eu-west-1"
cloudwatch = boto3.client("cloudwatch", region_name=region)
today = datetime.now() + timedelta(days=1) # today + 1 because we want all of today
two_weeks = timedelta(days=14)
start_date = today - two_weeks
ec2 = boto3.resource("ec2", region_name=region)
def get_available_volumes():
available_volumes = ec2.volumes.filter(
Filters=[{'Name': 'status', 'Values': ['available']}]
)
return available_volumes
def get_metrics(volume_id):
"""Get volume idle time on an individual volume over `start_date`
to today"""
metrics = cloudwatch.get_metric_statistics(
Namespace='AWS/EBS',
MetricName='VolumeIdleTime',
Dimensions=[{'Name': 'VolumeId', 'Value': volume_id}],
Period=3600, # every hour
StartTime=start_date,
EndTime=today,
Statistics=['Minimum'],
Unit='Seconds'
)
return metrics['Datapoints']
def is_candidate(volume_id):
"""Make sure the volume has not been used in the past two weeks"""
metrics = get_metrics(volume_id)
if len(metrics):
for metric in metrics:
# idle time is 5 minute interval aggregate so we use
# 299 seconds to test if we're lower than that
if metric['Minimum'] < 299:
return False
# if the volume had no metrics lower than 299 it's probably not
# actually being used for anything so we can include it as
# a candidate for deletion
return True
available_volumes = get_available_volumes()
candidate_volumes = [
volume
for volume in available_volumes
if is_candidate(volume.volume_id)
]
# delete the unused volumes
# WARNING -- THIS DELETES DATA
for candidate in candidate_volumes:
candidate.delete()
instances = ec2.instances.all()
my_images = ec2.images.filter(Owners=["my-account-id"])
# anything that's running or stopped we want to keep the AMI
good_images = set([instance.image_id for instance in ec2.instances.all()])
# build a dictionary of all the images that aren't in good_images
my_images_dict = {image.id: image for image in my_images if image.id not in good_images}
# now lets deregister all the AMIs older than two weeks
for image in image.values():
created_date = datetime.strptime(
image.creation_date, "%Y-%m-%dT%H:%M:%S.000Z")
if created_date < two_weeks_ago:
image.deregister()
images = ec2.images.all()
images = [image.id for image in images]
for snapshot in ec2.snapshots.filter(OwnerIds=["my-account-id"]):
r = re.match(r".*for (ami-.*) from.*", snapshot.description)
if r:
if r.groups()[0] not in images:
snapshot.delete()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment