The problem is not the tooling. It is the layer that is missing.
Every AWS account with more than a handful of teams has the same experience. The Cost and Usage Report exists. Cost Explorer exists. Someone has set up billing alerts on the root account. And still, at the end of the month, nobody can tell you with confidence which engineering team is responsible for the $280K EC2 line item.
The billing console tells you what was spent. It does not tell you who owns it. That gap — between cloud spend and organizational ownership — is the problem that most FinOps programs attempt to close with tag policies, and most never fully close.
Why tags alone fail at scale
Tag-based cost allocation works well when you control all the resources, all the engineers follow the tagging policy, and the policy was defined before the resources were created. In practice, none of those conditions hold consistently for teams managing $1M+ in annual cloud spend.
Resources created before the tag policy existed are untagged. Resources created by third-party tools, CDK constructs, or auto-scaling events often do not inherit tags from the parent resource. Lambda functions triggered from other services frequently have incomplete tag propagation. Shared services — a central RDS cluster, a transit VPC, a shared NAT Gateway — cannot be tagged to a single team because they genuinely belong to multiple teams in some proportion.
The result is that even organizations with active tag enforcement through AWS Service Control Policies typically see 15–30% of spend as unattributed in any given month. That is not a tagging failure. It is a structural limitation of tag-only attribution.
The attribution layer that fills the gap
What bridges the gap between billing data and team ownership is a resource ownership graph — a mapping from cloud resource IDs to the teams that declared, deployed, and are responsible for those resources. That graph already exists in most engineering organizations; it is just not connected to billing data.
Terraform state maps every resource ARN to the Terraform module and workspace that manages it. GitHub CODEOWNERS files map infrastructure repository paths to the teams that own them. PagerDuty service definitions map services to the on-call team. These three sources, combined and joined against the CUR, produce attribution coverage that reaches 90%+ of spend for most multi-team AWS environments — without requiring perfect tagging compliance.
The join is not trivial to build and maintain. Terraform state formats change across provider versions. CODEOWNERS files require consistent path conventions. PagerDuty service names do not always map cleanly to cloud resource naming conventions. But done correctly, the result is an attribution model that survives the reality of multi-team cloud environments rather than assuming perfect tagging compliance that rarely exists.
Showback vs. chargeback: which model makes attribution actionable
Once you have team-level attribution, the next question is what you do with it. The FinOps Foundation defines two models: showback (teams can see their cost, but it is informational only) and chargeback (teams are actually invoiced or charged back for their cloud spend).
Most engineering-first organizations start with showback and find that it produces behavioral change without the organizational friction of chargeback. Engineers who can see that their squad's weekly RDS spend spiked 40% last Tuesday are motivated to investigate — not because finance told them to, but because the data is in the same Slack channel where their on-call alerts land.
Chargeback is appropriate for organizations where cost accountability needs to flow to a P&L level — typically when engineering teams are organized as business units with their own cost budgets. For most product engineering organizations, showback at squad level, delivered weekly with actionable context, is sufficient to move teams from the FinOps Foundation Crawl stage toward Walk.
What team-level attribution actually requires
Building reliable team-level attribution from CUR data requires four things working together: a normalized billing data model that handles amortized Reserved Instance costs and Savings Plan distributions (not just on-demand line items); an ownership graph that maps resource IDs to teams across the three signal layers described above; a continuous update cadence that keeps the attribution current as teams and resources change; and a delivery mechanism that puts the data in front of engineers, not just in a dashboard that finance monitors.
The last point matters more than it seems. Attribution data that only lives in a finance tool or a quarterly report does not change engineering behavior. The goal of team-level attribution is to make cloud cost a first-class metric in the same cadence that engineers already work in — sprint reviews, on-call handoffs, weekly team syncs.