FinOps & optimisation CloudJuly 23, 2026

FinOps in 2025: Making Cloud Cost Control Actually Stick

Rightsizing, Savings Plans, showback and policy-as-code — a pragmatic FinOps playbook for AWS, GCP and Azure that survives contact with engineering teams.

Cloud bills rarely explode because of a single bad decision. They drift — an oversized RDS here, a forgotten GKE node pool there, a data egress pattern nobody reviewed since the last architecture change. By the time Finance escalates, you're already 30% over budget and hunting through Cost Explorer at midnight.

FinOps, as codified by the FinOps Foundation, is the operating model that prevents this drift. It's not a dashboard, it's a shared responsibility between engineering, finance and product. Here's how to make it work in practice across AWS, GCP and Azure.

The three phases, and where teams actually get stuck

The FinOps Framework defines three iterative phases: Inform, Optimize, Operate. Most organizations plateau in Inform — they buy a visibility tool, produce beautiful dashboards, and never actually change infrastructure behavior.

The fix is to treat each phase with concrete deliverables:

| Phase | Deliverable | Owner | |-------|-------------|-------| | Inform | Tagged resources ≥ 95%, showback per team | Platform + Finance | | Optimize | Rightsizing backlog, commitment coverage ≥ 70% | Engineering leads | | Operate | Budget alerts as code, anomaly detection SLA | FinOps practitioner |

Allocation: tagging is a product, not a chore

Without allocation, everything else is theater. Enforce a minimum tag schema (cost-center, environment, service, owner) and block untagged resources at deploy time. On AWS, use Service Control Policies combined with aws:RequestTag conditions. On Azure, use Azure Policy with deny effect. On GCP, enforce labels via Organization Policy and Terraform validation.

Example OPA/Rego policy for Terraform:

package terraform.tags

required_tags := {"cost-center", "environment", "service", "owner"}

deny[msg] {
  resource := input.resource_changes[_]
  resource.change.actions[_] == "create"
  provided := {k | resource.change.after.tags[k]}
  missing := required_tags - provided
  count(missing) > 0
  msg := sprintf("%s missing tags: %v", [resource.address, missing])
}

Run this in CI with Conftest or Checkov. No exceptions, no #TODO: add tags later.

Rightsizing: stop trusting p99 from three months ago

Native recommenders (AWS Compute Optimizer, Azure Advisor, GCP Recommender) are a decent starting point but they optimize per-resource, not per-workload. A right-sized EC2 fleet still wastes money if the ASG's target tracking is set to 30% CPU.

A workflow that actually reduces spend:

  1. Pull 30 days of CloudWatch/Monitoring metrics at 1-minute granularity.
  2. Compute p95 CPU, memory and network per workload — not per instance.
  3. Cross-reference with SLO error budgets. If a service has burned <10% of its budget, it's a rightsizing candidate.
  4. For Kubernetes, deploy KRR or Goldilocks to generate VPA recommendations, then apply them in Off mode first to validate.
  5. Automate downscaling for non-prod: nights and weekends alone typically cut dev/staging by 65%.

Commitments: the 70/20/10 rule

Savings Plans and Reserved Instances still deliver the highest ROI of any FinOps action — up to 72% off on-demand for 3-year all-upfront. The mistake is over-committing.

A reasonable target for stable workloads:

  • 70% covered by 1-year or 3-year commitments (Savings Plans on AWS, CUDs on GCP, Reserved Instances or Savings Plans on Azure)
  • 20% on-demand for elasticity
  • 10% Spot/Preemptible for fault-tolerant workloads (batch, CI, ML training)

On AWS, prefer Compute Savings Plans over EC2 Instance Savings Plans — they cover Fargate and Lambda and survive instance-family migrations. Review coverage monthly; commitments are not a set-and-forget instrument.

Governance: policy-as-code beats monthly review meetings

Monthly cost review meetings produce action items nobody executes. Replace them with automated guardrails:

  • Budget alerts as code via Terraform (aws_budgets_budget, azurerm_consumption_budget_subscription, google_billing_budget).
  • Anomaly detection: AWS Cost Anomaly Detection, GCP Recommender anomalies, or a cross-cloud tool like Vantage, CloudZero or the open-source OpenCost for Kubernetes.
  • Pre-merge cost estimation with Infracost in every Terraform PR. Any change adding >$500/month triggers a required review from the platform team.
  • Unit economics: track cost per tenant, per request, per GB processed. This is the metric that lets engineering discuss cost with product without defensiveness.

The FinOps checklist for Q1

  • [ ] Tag coverage ≥ 95%, enforced at admission
  • [ ] Showback report per team, delivered monthly and automatically
  • [ ] Commitment coverage ≥ 70% for stable compute
  • [ ] Rightsizing backlog with named owners and deadlines
  • [ ] Infracost or equivalent gating IaC PRs
  • [ ] Anomaly detection with a <24h response SLA
  • [ ] One unit-economics KPI per major product line
  • [ ] Quarterly Egress and storage-tier review (S3 Intelligent-Tiering, GCS Autoclass)

Key takeaways

  • Allocation first: no tagging, no FinOps. Enforce it at deploy time, not in retrospect.
  • Rightsize by workload, not by instance, and combine with autoscaling and off-hours schedules.
  • Commit to 70% coverage with Compute Savings Plans or CUDs; review monthly.
  • Codify governance: Infracost in CI, OPA on tags, budgets in Terraform. Meetings don't scale.
  • Track unit cost per tenant or per request — it's the only metric that aligns engineering, finance and product.
Share this article

Read also