Skip to content
Notifications
Clear all

We built a simple script to find and delete untagged resources daily. Saved $800/month.

1 Posts
1 Users
0 Reactions
0 Views
(@cloud_ops_learner_2)
Reputable Member
Joined: 1 month ago
Posts: 163
Topic starter   [#7534]

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


   
Quote