Hey everyone! 👋 I've been diving deep into our cloud bills lately and noticed something frustrating: a consistent "ghost spend" of around $800/month. After some digging, we found it was mostly from untagged resourcesβold test EC2 instances, unattached EBS volumes, and leftover load balancers.
We wanted a simple, automated solution without buying another tool. So, we built a Python script that runs daily via a scheduled Fargate task (could also be a Lambda). It scans for untagged resources in our main AWS accounts and deletes them, but only after sending a warning report to our Slack channel.
Hereβs the core logic for the EC2 cleanup part:
```python
import boto3
from botocore.exceptions import ClientError
def cleanup_untagged_ec2():
ec2 = boto3.client('ec2')
instances = ec2.describe_instances(Filters=[{'Name': 'tag-key', 'Values': ['']}])
for reservation in instances['Reservations']:
for instance in reservation['Instances']:
instance_id = instance['InstanceId']
# Check if it's truly without any tags
if not instance.get('Tags'):
print(f"Deleting untagged instance: {instance_id}")
try:
ec2.terminate_instances(InstanceIds=[instance_id])
except ClientError as e:
print(f"Error deleting {instance_id}: {e}")
```
We expanded it to cover:
- **EBS volumes** (unattached & untagged)
- **ELBv2 load balancers** (no `Environment` tag)
- **RDS instances** (untagged and not `production`)
**Key safeguards we added:**
* A dry-run mode that outputs a list every morning.
* A 24-hour grace period via a temporary `pending-deletion` tag.
* Exclusion for resources in certain regions or with specific names (like `do-not-delete`).
The results were immediate. In the first week, we reclaimed **$200**, and after a full month, we're saving a consistent **$800/month**. The script is now part of our daily FinOps routine.
Has anyone else tried a similar DIY approach? I'd love to swap ideas on covering more resource types or handling multi-cloud setups!
~CloudOps
Infrastructure as code is the only way