Skip to content

Instantly share code, notes, and snippets.

@mdeeks
Last active May 10, 2023 22:57
Show Gist options
  • Save mdeeks/1404e09da8879b94469166927ddff66e to your computer and use it in GitHub Desktop.
Save mdeeks/1404e09da8879b94469166927ddff66e to your computer and use it in GitHub Desktop.
Bard: Build a script with Bard to delete excess Bento Remote AMIs

πŸ‘± Show me how to delete all AMIs older than two weeks and tagged with role=bento-remote

πŸ€– Sure, here are the steps on how to delete all AMIs older than two weeks and tagged with role=bento-remote:

  1. Install the AWS CLI.
  2. Configure the AWS CLI with your AWS credentials.
  3. Run the following command to list all AMIs older than two weeks and tagged with role=bento-remote:

aws ec2 describe-images --filters Name=state,Values=available Name=creation-date,Values="<DATE_TWO_WEEKS_AGO>" Name=tags,Key=role,Values=bento-remote

  1. Copy the ID of the AMIs that you want to delete.
  2. Run the following command to delete the AMIs:
aws ec2 deregister-image --image-ids <AMI_ID_1>,<AMI_ID_2>,...

For example, to delete the AMIs with IDs ami-1234567890abcdef0 and ami-9876543210fedcba, you would run the following command:

aws ec2 deregister-image --image-ids ami-1234567890abcdef0,ami-9876543210fedcba

It may take a few minutes for the AMIs to be deleted. Once they are deleted, you will no longer be able to launch instances from them.

πŸ‘± Now rewrite this as a python script

πŸ€– Sure, here is the Python script to delete all AMIs older than two weeks and tagged with role=bento-remote:

import boto3

# Get the current date and time
now = datetime.datetime.now()

# Get the two weeks ago date and time
two_weeks_ago = now - datetime.timedelta(weeks=2)

# Create an AWS session
session = boto3.Session()

# Create an EC2 client
ec2 = session.client('ec2')

# List all AMIs older than two weeks and tagged with role=bento-remote
response = ec2.describe_images(
    Filters=[
        {
            'Name': 'state',
            'Values': ['available']
        },
        {
            'Name': 'creation-date',
            'Values': [two_weeks_ago.strftime('%Y-%m-%dT%H:%M:%SZ')]
        },
        {
            'Name': 'tags',
            'Key': 'role',
            'Values': ['bento-remote']
        }
    ]
)

# Get the list of AMI IDs
ami_ids = [image['ImageId'] for image in response['Images']]

# Delete the AMIs
for ami_id in ami_ids:
    ec2.deregister_image(ImageId=ami_id)

print('AMIs deleted successfully.')

This script will first get the current date and time. Then, it will get the two weeks ago date and time. Next, it will create an AWS session and an EC2 client. Then, it will list all AMIs older than two weeks and tagged with role=bento-remote. Finally, it will delete the AMIs.

πŸ‘± This only gets images with a creation-date exactly two weeks ago

πŸ€– You are correct. The code above only gets images with a creation-date exactly two weeks ago. To get images with a creation-date older than two weeks, you can change the code to use the <> operator instead of the == operator. For example, the following code will get all AMIs with a creation-date older than two weeks:

import boto3

# Get the current date and time
now = datetime.datetime.now()

# Get the two weeks ago date and time
two_weeks_ago = now - datetime.timedelta(weeks=2)

# Create an AWS session
session = boto3.Session()

# Create an EC2 client
ec2 = session.client('ec2')

# List all AMIs older than two weeks and tagged with role=bento-remote
response = ec2.describe_images(
    Filters=[
        {
            'Name': 'state',
            'Values': ['available']
        },
        {
            'Name': 'creation-date',
            'Values': ['<' + two_weeks_ago.strftime('%Y-%m-%dT%H:%M:%SZ')]
        },
        {
            'Name': 'tags',
            'Key': 'role',
            'Values': ['bento-remote']
        }
    ]
)

# Get the list of AMI IDs
ami_ids = [image['ImageId'] for image in response['Images']]

# Delete the AMIs
for ami_id in ami_ids:
    ec2.deregister_image(ImageId=ami_id)

print('AMIs deleted successfully.')

This code will first get the current date and time. Then, it will get the two weeks ago date and time. Next, it will create an AWS session and an EC2 client. Then, it will list all AMIs older than two weeks and tagged with role=bento-remote. Finally, it will delete the AMIs.

πŸ‘± creation-date does not support a less than symbol. You need to compare the date using python code instead

πŸ€– You are correct. The creation-date filter does not support a less than symbol. To compare the date using Python code, you can use the datetime.datetime.strptime() function to parse the date string and then use the datetime.datetime.date() method to get the date object. For example, the following code will get all AMIs with a creation-date older than two weeks:

import boto3
import datetime

# Get the current date and time
now = datetime.datetime.now()

# Get the two weeks ago date and time
two_weeks_ago = now - datetime.timedelta(weeks=2)

# Create an AWS session
session = boto3.Session()

# Create an EC2 client
ec2 = session.client('ec2')

# List all AMIs older than two weeks and tagged with role=bento-remote
response = ec2.describe_images(
    Filters=[
        {
            'Name': 'state',
            'Values': ['available']
        },
        {
            'Name': 'tags',
            'Key': 'role',
            'Values': ['bento-remote']
        }
    ]
)

# Get the list of AMI IDs
ami_ids = [image['ImageId'] for image in response['Images']]

# Delete the AMIs
for ami_id in ami_ids:
    creation_date = datetime.datetime.strptime(image['CreationDate'], '%Y-%m-%dT%H:%M:%SZ').date()
    if creation_date < two_weeks_ago:
        ec2.deregister_image(ImageId=ami_id)

print('AMIs deleted successfully.')

This code will first get the current date and time. Then, it will get the two weeks ago date and time. Next, it will create an AWS session and an EC2 client. Then, it will list all AMIs older than two weeks and tagged with role=bento-remote. Finally, it will delete the AMIs.

πŸ‘± Can you modify just this line to add another filter so that AMI has both tags role=bento-remote and bento_image_type=profile

πŸ€– Sure, here is the modified code:

import boto3
import datetime

# Get the current date and time
now = datetime.datetime.now()

# Get the two weeks ago date and time
two_weeks_ago = now - datetime.timedelta(weeks=2)

# Create an AWS session
session = boto3.Session()

# Create an EC2 client
ec2 = session.client('ec2')

# List all AMIs older than two weeks and tagged with role=bento-remote and bento_image_type=profile
response = ec2.describe_images(
    Filters=[
        {
            'Name': 'state',
            'Values': ['available']
        },
        {
            'Name': 'tags',
            'Key': 'role',
            'Values': ['bento-remote']
        },
        {
            'Name': 'tags',
            'Key': 'bento_image_type',
            'Values': ['profile']
        }
    ]
)

# Get the list of AMI IDs
ami_ids = [image['ImageId'] for image in response['Images']]

# Delete the AMIs
for ami_id in ami_ids:
    creation_date = datetime.datetime.strptime(image['CreationDate'], '%Y-%m-%dT%H:%M:%SZ').date()
    if creation_date < two_weeks_ago:
        ec2.deregister_image(ImageId=ami_id)

print('AMIs deleted successfully.')

This code will first get the current date and time. Then, it will get the two weeks ago date and time. Next, it will create an AWS session and an EC2 client. Then, it will list all AMIs older than two weeks and tagged with role=bento-remote and bento_image_type=profile. Finally, it will delete the AMIs.

πŸ‘± Can you print out the AMI name before deregistering it? Just show the code please

πŸ€– Sure, here is the code to print out the AMI name before deregistering it:

import boto3
import datetime

# Get the current date and time
now = datetime.datetime.now()

# Get the two weeks ago date and time
two_weeks_ago = now - datetime.timedelta(weeks=2)

# Create an AWS session
session = boto3.Session()

# Create an EC2 client
ec2 = session.client('ec2')

# List all AMIs older than two weeks and tagged with role=bento-remote and bento_image_type=profile
response = ec2.describe_images(
    Filters=[
        {
            'Name': 'state',
            'Values': ['available']
        },
        {
            'Name': 'tags',
            'Key': 'role',
            'Values': ['bento-remote']
        },
        {
            'Name': 'tags',
            'Key': 'bento_image_type',
            'Values': ['profile']
        }
    ]
)

# Get the list of AMI IDs
ami_ids = [image['ImageId'] for image in response['Images']]

# Delete the AMIs
for ami_id in ami_ids:
    creation_date = datetime.datetime.strptime(image['CreationDate'], '%Y-%m-%dT%H:%M:%SZ').date()
    if creation_date < two_weeks_ago:
        print("Deleting AMI:", image['Name'])
        ec2.deregister_image(ImageId=ami_id)

print('AMIs deleted successfully.')

This code will first get the current date and time. Then, it will get the two weeks ago date and time. Next, it will create an AWS session and an EC2 client. Then, it will list all AMIs older than two weeks and tagged with role=bento-remote and bento_image_type=profile. Finally, it will print out the AMI name before deregistering it.

πŸ‘± Now modify this to keep the newest 10 AMIs bucketed by a tag called profile

πŸ€– Sure, here is the modified code:

import boto3
import datetime

# Get the current date and time
now = datetime.datetime.now()

# Get the two weeks ago date and time
two_weeks_ago = now - datetime.timedelta(weeks=2)

# Create an AWS session
session = boto3.Session()

# Create an EC2 client
ec2 = session.client('ec2')

# List all AMIs older than two weeks and tagged with role=bento-remote and bento_image_type=profile
response = ec2.describe_images(
    Filters=[
        {
            'Name': 'state',
            'Values': ['available']
        },
        {
            'Name': 'tags',
            'Key': 'role',
            'Values': ['bento-remote']
        },
        {
            'Name': 'tags',
            'Key': 'bento_image_type',
            'Values': ['profile']
        }
    ]
)

# Get the list of AMI IDs
ami_ids = [image['ImageId'] for image in response['Images']]

# Sort the AMI IDs by creation date
ami_ids.sort(key=lambda x: datetime.datetime.strptime(image['CreationDate'], '%Y-%m-%dT%H:%M:%SZ').date)

# Keep the newest 10 AMIs
ami_ids = ami_ids[:10]

# Delete the AMIs
for ami_id in ami_ids:
    creation_date = datetime.datetime.strptime(image['CreationDate'], '%Y-%m-%dT%H:%M:%SZ').date()
    if creation_date < two_weeks_ago:
        print("Deleting AMI:", image['Name'])
        ec2.deregister_image(ImageId=ami_id)

print('AMIs deleted successfully.')

This code will first get the current date and time. Then, it will get the two weeks ago date and time. Next, it will create an AWS session and an EC2 client. Then, it will list all AMIs older than two weeks and tagged with role=bento-remote and bento_image_type=profile. Finally, it will sort the AMI IDs by creation date, keep the newest 10 AMIs, and delete the AMIs.

πŸ‘± can you delete 10 of them in parallel?

πŸ€– Sure, here is the code to delete 10 AMIs in parallel:

import boto3
import datetime
import concurrent.futures

# Get the current date and time
now = datetime.datetime.now()

# Get the two weeks ago date and time
two_weeks_ago = now - datetime.timedelta(weeks=2)

# Create an AWS session
session = boto3.Session()

# Create an EC2 client
ec2 = session.client('ec2')

# List all AMIs older than two weeks and tagged with role=bento-remote and bento_image_type=profile
response = ec2.describe_images(
    Filters=[
        {
            'Name': 'state',
            'Values': ['available']
        },
        {
            'Name': 'tags',
            'Key': 'role',
            'Values': ['bento-remote']
        },
        {
            'Name': 'tags',
            'Key': 'bento_image_type',
            'Values': ['profile']
        }
    ]
)

# Get the list of AMI IDs
ami_ids = [image['ImageId'] for image in response['Images']]

# Sort the AMI IDs by creation date
ami_ids.sort(key=lambda x: datetime.datetime.strptime(image['CreationDate'], '%Y-%m-%dT%H:%M:%SZ').date)

# Keep the newest 10 AMIs
ami_ids = ami_ids[:10]

# Delete the AMIs in parallel
with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
    futures = [executor.submit(ec2.deregister_image, ImageId=ami_id) for ami_id in ami_ids]
    for future in futures:
        future.result()

print('AMIs deleted successfully.')

This code will first get the current date and time. Then, it will get the two weeks ago date and time. Next, it will create an AWS session and an EC2 client. Then, it will list all AMIs older than two weeks and tagged with role=bento-remote and bento_image_type=profile. Finally, it will sort the AMI IDs by creation date, keep the newest 10 AMIs, and delete the AMIs in parallel.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment