Created
February 9, 2017 23:57
-
-
Save BenHigginbottom/d4b0e3ea9c807187315257d195f2c3b4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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