Idle Elastic IPs and unused GCP static IPs: a monthly FinOps review

Since February 1, 2024, AWS bills USD 0.005 per hour for every public IPv4 address, attached to a resource or not (AWS announcement). At 730 hours, that is USD 3.65 per month per address. On GCP the gap between idle and used is wider: a reserved static external IP assigned to nothing costs USD 0.01 per hour, against USD 0.005 for the same address in use by a standard VM, in US regions (Google Cloud network pricing). Unused, it costs USD 7.30 per month instead of USD 3.65.

One address does not move an invoice. The trouble is that an IP has no metrics, fires no alerts and takes no space, so nothing prompts anyone to look at it. It shows up on the bill and nowhere else, as a small line that repeats every month. That makes it a better fit for a recurring review than for a one-off cleanup. What follows is that review, ordered by the FinOps phases.

Inform: build the list with read-only access

Finding idle addresses does not require the right to delete them, so a read-only role is enough.

On AWS, list the Elastic IPs with no association. The command works per region, so repeat it in each region the account uses:

aws ec2 describe-addresses 
  --query "Addresses[?AssociationId==null].[PublicIp,AllocationId]" 
  --output table

That filter misses one case: an Elastic IP associated with a network interface that has no instance behind it. It reads as associated and serves nobody. To catch it, list the interfaces in the available status:

aws ec2 describe-network-interfaces --filters Name=status,Values=available

On GCP, list the reserved external addresses nobody uses:

gcloud compute addresses list 
  --filter="status=RESERVED AND addressType=EXTERNAL" 
  --format="table(name,address,region,status)"

Keep in mind what the AWS list leaves out. The USD 0.005 rate also applies to the public IPs AWS assigns to instances, load balancers and NAT gateways. Those addresses are in use and they bill at the same rate, so they belong in the cost report next to the idle ones.

Optimize: explain each address before releasing it

The usual cause is an incomplete deletion. Somebody deletes a VM by hand from the console and what surrounded it stays:

  • On AWS, an Elastic IP outlives its instance. After termination the address stays allocated to the account, unassociated, and keeps billing.
  • On GCP, a static address goes back to the RESERVED status when the VM that used it goes away.
  • On both, test environments leave addresses behind: somebody reserves an IP for a temporary setup, the setup goes away and the IP does not.

A worked example with the AWS rate: forty addresses forgotten over three years, across accounts, cost 40 × USD 3.65 = USD 146 per month, or USD 1,752 per year, and buy nothing. On GCP in US regions, each unused reserved address you release takes USD 7.30 per month off the bill.

The list from the first step holds candidates, not confirmed orphans. If a command could not read a field, because of missing permissions or a region that did not answer, the result for that address is “unknown”, not “free”. The two errors do not cost the same. An unused IP costs USD 3.65 per month on AWS. An IP released by mistake does not come back, and if it sat in a DNS record or on a customer allowlist, the outage is immediate. Paying one more month for an address you cannot explain is the cheaper error.

Operate: the monthly checklist

  1. Run the two AWS commands in every region in use, for every account.
  2. Run the gcloud command in every project.
  3. Mark each result as orphaned, in use or unknown.
  4. For each orphan, check DNS records and customer allowlists before you release it.
  5. Multiply the orphans by the rate per hour and 730 hours, and report the monthly figure next to the previous one.
  6. Write down where each orphan came from (a terminated instance, a deleted VM, a test environment) and take it to the team that owns that deletion procedure.
  7. Leave the unknowns out of the savings number until somebody can read the missing field.

Step 7 keeps the report honest: an address nobody could verify is not a saving yet.

We build Control Cloud, a multi-cloud inventory and pre-deploy validation tool that reads your clouds with read-only credentials; this article adapts a note from our blog that also covers Azure.

controlcloud
controlcloud
Articles: 1