Skip to main content

On This Page

Automating AWS Cost Optimization: Audit Cloud Waste in 5 Minutes with Python

2 min read
Share

These articles are AI-generated summaries. Please check the original sources for full details.

How to audit your AWS account for waste in 5 minutes using Python

AWS infrastructure often accumulates hidden costs through unattached resources that go unnoticed without automated monitoring. A single idle Elastic IP costs $3.65 monthly, while unattached EBS volumes can charge up to $0.125 per GB depending on the volume type.

Why This Matters

While cloud scalability is a primary benefit of AWS, the lack of automated cleanup leads to significant financial leakages where companies pay for ‘ghost’ resources. Technical debt in the form of abandoned snapshots and unattached storage creates a gap between intended infrastructure architecture and actual billing reality, often resulting in hundreds of dollars of monthly waste across standard accounts.

Key Insights

  • Unattached EBS volumes in ‘available’ state incur charges regardless of usage; gp2 volumes typically cost $0.10 per GB-month (Tripathi, 2026).
  • Idle Elastic IP addresses are billed at a flat rate of $3.65 per month when not associated with a running instance.
  • Snapshots older than 90 days represent stale data billed at approximately $0.05 per GB-month.
  • The Boto3 library for Python allows for programmatic auditing of EC2, EBS, and STS services via standard API calls.
  • Least-privilege auditing requires a specific IAM policy allowing ‘ec2:DescribeVolumes’ and ‘ec2:DescribeAddresses’ to maintain security.

Working Examples

IAM Read-Only Policy for secure waste auditing

{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Action": ["ec2:DescribeInstances", "ec2:DescribeVolumes", "ec2:DescribeAddresses", "ec2:DescribeSnapshots", "cloudwatch:GetMetricStatistics", "sts:GetCallerIdentity"], "Resource": "*"}]}

Python function to identify and calculate costs of unattached EBS volumes

import boto3\ndef find_unattached_ebs(region='us-east-1'):\n    ec2 = boto3.client('ec2', region_name=region)\n    volumes = ec2.describe_volumes(Filters=[{'Name': 'status', 'Values': ['available']}])\n    monthly_waste = 0\n    findings = []\n    pricing = {'gp2': 0.10, 'gp3': 0.08, 'io1': 0.125}\n    for vol in volumes['Volumes']:\n        size = vol['Size']\n        vol_type = vol['VolumeType']\n        rate = pricing.get(vol_type, 0.10)\n        monthly_cost = size * rate\n        monthly_waste += monthly_cost\n        findings.append({'id': vol['VolumeId'], 'size_gb': size, 'type': vol_type, 'monthly_cost': monthly_cost})\n    return findings, monthly_waste

Practical Applications

  • Use Case: Monthly automated reporting via Boto3 to identify idle Elastic IPs. Pitfall: Manually checking the AWS Console leads to human error and missed regional resources.
  • Use Case: Snapshot lifecycle management for data older than 90 days. Pitfall: Retaining snapshots indefinitely without a deletion policy leads to silent, compounding storage costs.

References:

Continue reading

Next article

How to Debug Duplicate Cron Job Executions on Mac Mini

Related Content