aws-cost-cleanup
Automated cleanup of unused AWS resources to reduce costs
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Automated cleanup of unused AWS resources to reduce costs
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
| name | aws-cost-cleanup |
| description | Automated cleanup of unused AWS resources to reduce costs |
| risk | safe |
| source | community |
| date_added | 2026-02-27 |
Automate the identification and removal of unused AWS resources to eliminate waste.
Use this skill when you need to automatically clean up unused AWS resources to reduce costs and eliminate waste.
Storage
Compute
Networking
#!/bin/bash
# cleanup-unused-ebs.sh
echo "Finding unattached EBS volumes..."
VOLUMES=$(aws ec2 describe-volumes \
--filters Name=status,Values=available \
--query 'Volumes[*].VolumeId' \
--output text)
for vol in $VOLUMES; do
echo "Would delete: $vol"
# Uncomment to actually delete:
# aws ec2 delete-volume --volume-id $vol
done
#!/bin/bash
# cleanup-old-snapshots.sh
CUTOFF_DATE=$(date -d '90 days ago' --iso-8601)
aws ec2 describe-snapshots --owner-ids self \
--query "Snapshots[?StartTime<='$CUTOFF_DATE'].[SnapshotId,StartTime,VolumeSize]" \
--output text | while read snap_id start_time size; do
echo "Snapshot: $snap_id (Created: $start_time, Size: ${size}GB)"
# Uncomment to delete:
# aws ec2 delete-snapshot --snapshot-id $snap_id
done
#!/bin/bash
# release-unused-eips.sh
aws ec2 describe-addresses \
--query 'Addresses[?AssociationId==null].[AllocationId,PublicIp]' \
--output text | while read alloc_id public_ip; do
echo "Would release: $public_ip ($alloc_id)"
# Uncomment to release:
# aws ec2 release-address --allocation-id $alloc_id
done
# Apply lifecycle policy to transition old objects to cheaper storage
cat > lifecycle-policy.json <<EOF
{
"Rules": [
{
"Id": "Archive old objects",
"Status": "Enabled",
"Transitions": [
{
"Days": 90,
"StorageClass": "STANDARD_IA"
},
{
"Days": 180,
"StorageClass": "GLACIER"
}
],
"NoncurrentVersionExpiration": {
"NoncurrentDays": 30
},
"AbortIncompleteMultipartUpload": {
"DaysAfterInitiation": 7
}
}
]
}
EOF
aws s3api put-bucket-lifecycle-configuration \
--bucket my-bucket \
--lifecycle-configuration file://lifecycle-policy.json
#!/usr/bin/env python3
# calculate-savings.py
import boto3
from datetime import datetime, timedelta
ec2 = boto3.client('ec2')
# Calculate EBS volume savings
volumes = ec2.describe_volumes(
Filters=[{'Name': 'status', 'Values': ['available']}]
)
total_size = sum(v['Size'] for v in volumes['Volumes'])
monthly_cost = total_size * 0.10 # $0.10/GB-month for gp3
print(f"Unattached EBS Volumes: {len(volumes['Volumes'])}")
print(f"Total Size: {total_size} GB")
print(f"Monthly Savings: ${monthly_cost:.2f}")
# Calculate Elastic IP savings
addresses = ec2.describe_addresses()
unused = [a for a in addresses['Addresses'] if 'AssociationId' not in a]
eip_cost = len(unused) * 3.65 # $0.005/hour * 730 hours
print(f"\nUnused Elastic IPs: {len(unused)}")
print(f"Monthly Savings: ${eip_cost:.2f}")
print(f"\nTotal Monthly Savings: ${monthly_cost + eip_cost:.2f}")
print(f"Annual Savings: ${(monthly_cost + eip_cost) * 12:.2f}")
import boto3
from datetime import datetime, timedelta
def lambda_handler(event, context):
ec2 = boto3.client('ec2')
# Delete unattached volumes older than 7 days
volumes = ec2.describe_volumes(
Filters=[{'Name': 'status', 'Values': ['available']}]
)
cutoff = datetime.now() - timedelta(days=7)
deleted = 0
for vol in volumes['Volumes']:
create_time = vol['CreateTime'].replace(tzinfo=None)
if create_time < cutoff:
try:
ec2.delete_volume(VolumeId=vol['VolumeId'])
deleted += 1
print(f"Deleted volume: {vol['VolumeId']}")
except Exception as e:
print(f"Error deleting {vol['VolumeId']}: {e}")
return {
'statusCode': 200,
'body': f'Deleted {deleted} volumes'
}
Discovery Phase (Read-only)
Validation Phase
Execution Phase (Dry-run first)
Verification Phase
Discovery
Execution
Automation
# Run cleanup across multiple accounts
for account in $(aws organizations list-accounts \
--query 'Accounts[*].Id' --output text); do
echo "Checking account: $account"
aws ec2 describe-volumes \
--filters Name=status,Values=available \
--profile account-$account
done
# Create CloudWatch alarm for cost anomalies
aws cloudwatch put-metric-alarm \
--alarm-name high-cost-alert \
--alarm-description "Alert when daily cost exceeds threshold" \
--metric-name EstimatedCharges \
--namespace AWS/Billing \
--statistic Maximum \
--period 86400 \
--evaluation-periods 1 \
--threshold 100 \
--comparison-operator GreaterThanThreshold
Medium Risk Actions:
Always:
# Analyze and cleanup in one command
kiro-cli chat "Use aws-cost-cleanup to find and remove unused resources"
# Generate cleanup script
kiro-cli chat "Create a safe cleanup script for my AWS account"
# Schedule automated cleanup
kiro-cli chat "Set up weekly automated cleanup using aws-cost-cleanup"
You are a Python project architecture expert specializing in scaffolding production-ready Python applications. Generate complete project structures with modern tooling (uv, FastAPI, Django), type hint (Alias for python-development-python-scaffold)
Diagnose slow React components and suggest targeted performance fixes.
Optimizes AI agent performance by pruning redundant context, managing token usage, and enforcing ultra-concise, direct-to-value responses.
Automate Reddit tasks via Rube MCP (Composio): search subreddits, create posts, manage comments, and browse top content. Always search tools first for current schemas.
Generate walkthrough videos from Stitch projects using Remotion with smooth transitions, zooming, and text overlays
Master Rust async programming with Tokio, async traits, error handling, and concurrent patterns. Use when building async Rust applications, implementing concurrent systems, or debugging async code.