How to Delete EC2 AMI and Associated Snapshots Using AWS CLI


2 views

When working with AWS EC2, deleting an AMI (Amazon Machine Image) requires more than just deregistering the image. The complete process involves:

  1. Deregistering the AMI itself
  2. Deleting the associated EBS snapshots
  3. Cleaning up any related resources

Here's the complete workflow to properly delete an EC2 AMI:

1. First, identify the AMI and its snapshots

aws ec2 describe-images --image-ids ami-1234567890abcdef0

This will return details including the snapshot IDs associated with the AMI.

2. Deregister the AMI

aws ec2 deregister-image --image-id ami-1234567890abcdef0

3. Delete the associated snapshots

The snapshots won't be automatically deleted when you deregister the AMI. You need to delete them separately:

aws ec2 delete-snapshot --snapshot-id snap-1234567890abcdef0

For frequent AMI management, consider this bash script:

#!/bin/bash
AMI_ID="ami-1234567890abcdef0"

# Get snapshot IDs
SNAPSHOTS=$(aws ec2 describe-images --image-ids $AMI_ID \
    --query 'Images[0].BlockDeviceMappings[].Ebs.SnapshotId' \
    --output text)

# Deregister AMI
aws ec2 deregister-image --image-id $AMI_ID

# Delete snapshots
for SNAPSHOT in $SNAPSHOTS; do
    aws ec2 delete-snapshot --snapshot-id $SNAPSHOT
done

echo "AMI $AMI_ID and associated snapshots deleted successfully"
  • Verify the AMI isn't being used before deletion
  • Check IAM permissions (needs ec2:DeregisterImage and ec2:DeleteSnapshot)
  • AMI deletion is irreversible
  • Snapshots may take time to delete depending on size

Error: "UnauthorizedOperation"
Fix: Ensure your IAM policy includes ec2:DeleteSnapshot and ec2:DeregisterImage permissions

Error: "InvalidAMIID.Unavailable"
Fix: The AMI may already be deregistered - verify its status first


When working with AWS EC2 instances, you'll often need to manage AMIs (Amazon Machine Images). While creating AMIs is straightforward using ec2-create-image, the deletion process requires more attention because AMIs consist of multiple components that need proper cleanup.

A common mistake is using only the aws ec2 deregister-image command, which only removes the AMI registration but leaves underlying EBS snapshots untouched. This leads to:

  • Orphaned snapshots consuming storage
  • Unnecessary storage costs
  • Cluttered AWS resources

Here's the proper way to delete an AMI and its associated snapshots:

# First, get the snapshot IDs associated with the AMI
aws ec2 describe-images --image-ids ami-12345678 --query "Images[0].BlockDeviceMappings[].Ebs.SnapshotId" --output text

# Deregister the AMI
aws ec2 deregister-image --image-id ami-12345678

# Delete each associated snapshot
aws ec2 delete-snapshot --snapshot-id snap-1234567890abcdef0

For regular maintenance, you might want to automate this process:

#!/bin/bash

AMI_ID=$1

# Get snapshot IDs
SNAPSHOT_IDS=$(aws ec2 describe-images --image-ids $AMI_ID \
  --query "Images[0].BlockDeviceMappings[].Ebs.SnapshotId" \
  --output text)

# Deregister AMI
aws ec2 deregister-image --image-id $AMI_ID

# Delete snapshots
for SNAPSHOT_ID in $SNAPSHOT_IDS
do
  aws ec2 delete-snapshot --snapshot-id $SNAPSHOT_ID
  echo "Deleted snapshot: $SNAPSHOT_ID"
done

echo "AMI $AMI_ID and its snapshots have been completely removed"
  • Verify the AMI isn't being used before deletion
  • Check AWS regions if you're working across multiple regions
  • Consider creating backups before deletion if the AMI is critical
  • Monitor AWS Billing to confirm storage costs decrease

For enterprise environments, consider setting up a Lambda function triggered by CloudWatch Events to periodically clean up old AMIs:

import boto3
import datetime

def lambda_handler(event, context):
    ec2 = boto3.client('ec2')
    
    # Get all AMIs older than 30 days
    amis = ec2.describe_images(Filters=[{'Name': 'owner-id', 'Values': ['YOUR_ACCOUNT_ID']}])
    
    for ami in amis['Images']:
        creation_date = datetime.datetime.strptime(ami['CreationDate'], '%Y-%m-%dT%H:%M:%S.%fZ')
        if (datetime.datetime.now() - creation_date).days > 30:
            # Deregister AMI and delete snapshots
            snapshot_ids = [bdm['Ebs']['SnapshotId'] for bdm in ami['BlockDeviceMappings'] if 'Ebs' in bdm]
            ec2.deregister_image(ImageId=ami['ImageId'])
            for snapshot_id in snapshot_ids:
                ec2.delete_snapshot(SnapshotId=snapshot_id)
    
    return {'statusCode': 200, 'body': 'AMI cleanup completed'}