Hey everyone,
Ran into a classic cost creep issue last month after scaling up and down some test GKE clusters. Turns out we had a bunch of orphaned persistent disks, load balancers, and even some firewall rules hanging around. Our cloud bill had some unpleasant surprises 😅
I've put together a script that's been pretty handy for us. It helps identify and clean up resources in a GCP project that are no longer attached to a running GKE cluster. It's not a silver bullet, and you should **always** review the list before deleting anything, but it's saved us a lot of manual hunting.
The script focuses on:
* Finding and listing unattached persistent disks (with the `gke-` prefix)
* Identifying load balancer components (forwarding rules, target pools, health checks) with old cluster UIDs
* Listing firewall rules referencing deleted cluster names
It's a starting pointβyou'll want to adjust the filters for your own naming conventions. We run it in dry-run mode first and always double-check the output against the GCP console.
Has anyone else built similar tooling for other managed distributions (like EKS or AKS)? I'm curious if the orphaned resource patterns are different. Also, what's your team's process for catching these? Scheduled audits, or tools like `kube-janitor`?
Best, Julie
Great point about always running it in dry-run mode first. That's a step I've seen people skip, and it can lead to some real headaches.
Regarding other platforms, in my experience EKS tends to leave behind more network interfaces (ENIs) than disks, especially with certain CNI plugins. The cleanup logic ends up being quite different. Anyone else have AKS stories?
Be kind, stay curious.
Your script's focus on GCP's load balancer components is the right approach. The real complexity there is the dependency chain: deleting a forwarding rule before its backend service can leave you with partial orphans. We've had to extend similar tooling to parse the description fields on these resources, which sometimes contain the cluster UID you mentioned, but not always in a consistent format.
For firewall rules, the pattern gets even more nuanced in projects using shared VPCs or GKE Network Policy. Rules might be created by the GKE control plane but modified later by a separate security team, making automated identification risky. We ended up tagging all GCP resources at creation via a cluster-admission webhook, then using those tags for cleanup, which is more reliable than name parsing.
Have you considered integrating this into your CI/CD pipeline to run as a post-job after cluster deletion, rather than as a periodic manual check?