How to Delete EC2 AMI and Associated Snapshots Using AWS CLI


11 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'}