Tagging & cost allocation
Every previous lesson assumed you could answer one question: who or what is this cost for? That question is cost allocation, and it is the foundation the entire FinOps discipline stands on. The hardest, most expensive cloud bills aren't the big ones — they're the unattributed ones, where spend arrives as a single opaque number and no team feels it's theirs. You cannot optimize, rightsize, or hold anyone accountable for a cost nobody owns. This lesson is how you make every dollar owned.
The core problem: an unowned bill is an unmanaged bill
A cloud account, by default, produces one giant invoice. There's no built-in notion of "this $30k is the payments team's, that $12k is search's." Without that breakdown:
- No engineer sees the cost of their own decisions, so nobody optimizes.
- Finance sees a scary total it can't explain or push back on.
- The instinct from the unit-economics lesson — cost per team, per feature, per customer — is impossible to compute.
The fix is cost allocation: attributing every dollar to a meaningful owner — a team, service, environment, or customer. And the primary mechanism for it is tagging.
Tags: the labels that make cost attributable
A tag (called a label on GCP/Kubernetes) is a key–value pair you attach to a resource — team: payments, environment: prod, service: checkout, cost-center: 4012. The provider then lets you slice the bill by any tag: "show me all spend where team=payments." Tags are how an opaque total becomes a set of owned line items.
This sounds trivial and is, in practice, the part most teams get wrong — because tagging only works if it's consistent and near-universal. One untagged resource, one team that writes Team while another writes team, one project that skips environment, and your allocation springs leaks. The discipline is the whole game.
That unallocated slice is the metric to watch: it's the spend no tag claims. Mature teams track percent-allocated as a top-line FinOps health number and drive the unallocated slice toward zero.
:::tip Making tagging stick (it won't happen by goodwill) Tagging by politeness always decays. Enforce it structurally:
- Define a small, required tag set (e.g.
team,environment,service,cost-center) — few enough that people comply, enough to allocate. - Enforce at provisioning time in Infrastructure as Code (Chapter 3): make the module require the tags, so an untagged resource can't be created.
- Use policy-as-code / tag policies to reject or flag untagged resources.
- Report the unallocated % back to teams weekly so gaps are visible. Tagging is a day-one design decision, not a cleanup project — retro-tagging thousands of live resources is miserable. :::
Showback vs chargeback
Once spend is allocated, you do something with the breakdown. Two models:
- Showback — you show each team what it spends, but the bill is still paid centrally. It's informational: a dashboard, a weekly email, a number in standup. No money actually moves between budgets.
- Chargeback — you charge each team's own budget for its spend. The cost is internally billed to the team, hitting their P&L. It's accounting, not just information.
Both require the same allocation foundation; they differ in teeth. Chargeback creates the strongest accountability (it's your real budget) but is heavier — it needs accurate allocation finance will defend, and it can breed cost-avoidance gaming. Showback is lighter and, remarkably, most of the benefit.
:::note Why showback alone reduces waste 15–20% A consistent FinOps finding: simply showing engineers their team's spend — with no chargeback, no budget consequence — cuts waste on the order of 15–20%. The mechanism is plain: people optimize what they can see. An engineer who learns their forgotten staging cluster costs $4k/month turns it off — not because they were billed, but because the waste became visible and embarrassing. Visibility is most of the lever. This is why "start with showback" is the standard advice: it's cheap, low-conflict, and captures the bulk of the savings before you ever take on the politics of chargeback. :::
The usual maturity path: allocate (tag) → showback → optimize → and only later, if needed, chargeback. Stopping at "we have a showback dashboard" with no optimization loop is a real failure mode — visibility is necessary but not sufficient; it has to feed action (the FinOps loop).
The hard case: shared Kubernetes cost
Tagging cleanly attributes a whole VM or bucket to one team. But a shared Kubernetes cluster (Chapter 4) breaks that model: one cluster, one set of nodes, one bill — but a dozen teams' pods packed onto it. The cloud provider only sees "nodes," not "which team's pod used which slice." How do you split one cluster bill by team?
This is Kubernetes cost allocation, and it needs a tool the cloud bill alone can't provide. The approach:
- Split the node cost down to the pod level using each pod's resource requests (what it reserved — recall rightsizing: requests are what you effectively pay for) and actual usage.
- Aggregate pods up by namespace, label, or team to produce a per-team share of the cluster.
- Crucially, account for the idle / unallocated cost: the reserved-but-unused capacity and the shared overhead (the control plane, system pods, half-empty nodes). This idle cost is real money that belongs to no single pod — and pretending it's zero is a classic mistake.
OpenCost (the open, CNCF-backed standard) and Kubecost (built on it) do exactly this — they read requests/usage and the cloud's node prices and produce per-namespace, per-team, per-pod cost, explicitly including the idle/unallocated bucket. Treating the cluster bill as one opaque number — never splitting it by namespace, never surfacing idle — is one of the most common allocation gaps, and these tools exist precisely to close it.
FOCUS: one schema across clouds
A final allocation headache: every cloud formats its billing data differently. AWS's Cost and Usage Report, GCP's billing export, and Azure's cost exports use different column names, units, and structures for the same concepts. A team on multiple clouds (or comparing tools) has to normalize all of it by hand.
FOCUS — the FinOps Open Cost and Usage Specification — is an open standard that defines a single normalized schema for billing data: common column names and definitions for cost, usage, resource, tags, and discounts, so AWS, GCP, Azure, and SaaS bills all map into one consistent shape. Its value is durable and growing: instead of writing per-cloud parsers, you consume FOCUS-formatted data once, and any FOCUS-aware tool works across all your providers. As multi-cloud and cost-tooling proliferate, FOCUS is becoming the lingua franca of billing data — worth knowing by name.
A worked example
A platform team is asked "what does the search team cost us?" Trace the allocation:
- VMs and buckets tagged
team: search→ the bill slices straight to ~$12k. Easy, because tagging was enforced in their Terraform modules from day one. - The shared cluster has no per-team line — but OpenCost splits it by namespace:
search's pods reserved ~25% of cluster requests → ~$5k of the $20k cluster. - Idle cluster cost ($3k) is allocated proportionally or flagged as shared overhead, not hidden.
- Total search-team spend: ~$17k — now shown to the search team weekly. Within a month they spot a forgotten staging namespace and a 6×-oversized service (from rightsizing) and cut $3k themselves.
No chargeback, no mandate — just allocation plus visibility, and the team optimized its own waste. That's the 15–20% showback effect in one trace.
Common pitfalls
- Inconsistent or missing tags.
Teamvsteam, untagged resources — allocation springs leaks. Enforce a small required set in IaC. - Treating the cluster bill as one number. Never splitting shared Kubernetes cost by namespace/team, never surfacing idle. Use OpenCost/Kubecost.
- Ignoring idle/unallocated cost. Pretending reserved-but-unused and shared overhead don't exist. They're real money.
- Stopping at the dashboard. Showback with no optimization loop — visibility that never turns into action.
- Jumping to chargeback first. Taking on chargeback's politics and gaming before capturing the easy showback wins.
Why it matters
Cost allocation is the foundation of FinOps: an unowned bill is an unmanaged bill. Tags (key–value labels like team/environment/service) turn one opaque total into owned line items — but only if they're consistent and enforced in IaC, and you must drive the unallocated % toward zero. Showback (show teams their spend) versus chargeback (bill their budget): showback alone cuts waste 15–20% because people optimize what they see, so start there. Shared Kubernetes cost is the hard case — split it by namespace/team with OpenCost/Kubecost and don't hide the idle/unallocated bucket. FOCUS normalizes billing data across clouds into one schema. With cost now owned and visible, we can run it as a continuous discipline — the FinOps loop.
Where this leads: allocation is the Inform phase of the FinOps loop; without it the Optimize and Operate phases have nothing to act on.