TL;DR — Activating
aws:ecs:clusterNameandaws:ecs:serviceNamein Cost Allocation Tags is not enough to get per-cluster Fargate visibility. You also need Split Cost Allocation Data (SCAD) for ECS enabled in the payer account. Without it, 100% of your Fargate spend lands in the empty-tag bucket. Five steps below.
We run a multi-tenant SaaS on AWS. Nine ECS Fargate clusters across two regions. Each cluster maps roughly to a tenant — tenant-a-live, tenant-b-live, tenant-c-live, and so on. About $29,000/month goes to ECS Fargate.
Last week the CTO asked a reasonable question:
"What's the cost per tenant?"
Sure. Open Cost Explorer. Group by service. One line:
Amazon Elastic Container Service ............ $29,146
That's it. Nine clusters, dozens of services, one bar. This is the part of AWS cost management nobody warns you about.
What the AWS docs tell you to do
Open the Billing console → Cost Allocation Tags → AWS-generated tags tab. Activate:
aws:ecs:clusterNameaws:ecs:serviceName
The docs say these are auto-applied by AWS to every ECS task. Activate them, wait ~24 hours, group by tag in Cost Explorer. Done.
I activated them. Months ago.
Today I ran:
aws ce get-cost-and-usage \
--time-period Start=2026-04-28,End=2026-05-28 \
--granularity MONTHLY --metrics UnblendedCost \
--filter '{"Dimensions":{"Key":"SERVICE","Values":["Amazon Elastic Container Service"]}}' \
--group-by Type=TAG,Key=aws:ecs:clusterName
Result:
"Groups": [
{
"Keys": ["aws:ecs:clusterName$"],
"Metrics": {"UnblendedCost": {"Amount": "29146.11", "Unit": "USD"}}
}
]
100% of spend in one bucket — the empty one. The trailing $ after clusterName means "no tag value." Every dollar is unattributed.
Tags were marked Active in the console. The Cost Explorer dropdown even showed a few cluster names — demo-cluster, backup-cron-cluster-DONT-DELETE — but none of my production clusters. Total spend across the names that did show up: under $1.
The diagnostic walk
Step one — confirm the clusters exist:
aws ecs list-clusters --region us-east-1 --output text
tenant-a-live-cluster
tenant-b-live-cluster
tenant-b-ca-live-cluster
tenant-c-live-cluster
pre-production-cluster
core-platform-cluster
backup-script-cluster
Seven clusters. All running Fargate tasks. None in the Cost Explorer dropdown.
So aws:ecs:clusterName was marked Active. AWS was — theoretically — generating it. The console UI confirmed it. But billing records were getting no tag values for production tasks.
The missing piece: Split Cost Allocation Data
After more poking at AWS docs (specifically the Understanding split cost allocation data page in the CUR User Guide), the answer became clear:
AWS-generated ECS tags do not enrich your Fargate billing records with full task-level detail unless Split Cost Allocation Data (SCAD) for ECS is enabled in the payer account.
Activating the tag is necessary. It is not sufficient.
SCAD is a separate, payer-account-level setting. When enabled, AWS ingests telemetry from your ECS tasks and writes per-task cost data into the Cost and Usage Report under the splitLineItem/* columns — and it's what makes the AWS-generated ECS tags actually attach values to your billing rows. Without SCAD, those tags exist on your resources but are absent from the billing rows Cost Explorer queries against.
This is the single most expensive misunderstanding I've had with AWS billing.
The fix
Two things must be active, both in the payer/management account:
1. Activate the AWS-generated ECS tags
Billing console → Cost allocation tags → AWS-generated tags tab → activate:
aws:ecs:clusterNameaws:ecs:serviceName
Or via CLI:
aws ce update-cost-allocation-tags-status \
--cost-allocation-tags-status '[
{"TagKey":"aws:ecs:clusterName","Status":"Active"},
{"TagKey":"aws:ecs:serviceName","Status":"Active"}
]'
2. Enable Split Cost Allocation Data for ECS
Billing console → Cost Management Preferences → scroll to Split cost allocation data → click Edit → check "Include Amazon Elastic Container Service" → Save preferences.
Two gotchas:
- This setting is only available in the payer/management account. Member accounts will see a banner about "Account settings are only available for Payer and Regular Accounts." Switch roles before you go hunting.
- AWS docs scatter "Split Cost Allocation Data" across the EKS user guide, the CUR user guide, and the Cost Explorer pages. The setting itself lives in the Billing console preferences — not the Cost Explorer or CUR console.
3. (Optional but important) Backfill historical data
On the Cost Allocation Tags page there is a Backfill tags button in the top right. It retroactively populates billing records for up to 12 months with current tag values. If your clusters existed before activation, click this — otherwise you only get attribution going forward from today.
4. Wait ~24 hours
Cost Explorer is not real-time. New per-cluster breakdowns appear the day after enablement.
5. (Optional) Set up a CUR 2.0 export
If you want to slice this with Athena/QuickSight rather than Cost Explorer's UI, create a CUR 2.0 export with Include split cost allocation data checked. That gets you the per-task splitLineItem/NetSplitCost columns to query directly.
Verification
The morning after enabling, re-run the query:
aws ce get-cost-and-usage \
--time-period Start=$(date -d '1 day ago' +%Y-%m-%d),End=$(date +%Y-%m-%d) \
--granularity DAILY --metrics UnblendedCost \
--filter '{"And":[
{"Dimensions":{"Key":"SERVICE","Values":["Amazon Elastic Container Service"]}},
{"Dimensions":{"Key":"LINKED_ACCOUNT","Values":["<YOUR_ACCOUNT_ID>"]}}
]}' \
--group-by Type=TAG,Key=aws:ecs:clusterName --output table
You should see one row per cluster. Anything still in the aws:ecs:clusterName$ empty bucket is one of:
- Cluster-level overhead — CloudWatch Container Insights ingestion, ECR storage, NAT egress for tasks pulling images. This will always have some spend in the empty bucket.
- Pre-backfill historical data — if you skipped step 3, anything before today's enablement stays in the empty bucket forever.
If 100% of spend is still in the empty bucket after 24+ hours, SCAD didn't actually save. Open the preference page and check again — the Save button is at the bottom of a long form and doesn't always visibly confirm.
Bonus: per-tenant cost with custom tags
aws:ecs:clusterName is the AWS-generated path. If your cluster names don't cleanly map to tenants — or if you want a different rollup dimension (per-product, per-team, per-environment) — define your own tag in Terraform:
resource "aws_ecs_service" "api" {
name = "api"
cluster = aws_ecs_cluster.shared.arn
enable_ecs_managed_tags = true
propagate_tags = "SERVICE"
tags = {
Tenant = "tenant-a"
Environment = "production"
CostCenter = "platform"
}
}
Then activate Tenant / CostCenter in Cost Allocation Tags. Same 24-hour wait, same --group-by Type=TAG,Key=Tenant pattern.
The propagate_tags = "SERVICE" line is the one most people miss — without it, the service-level tags don't propagate to the tasks, and SCAD won't have the right tag on the task-level billing rows.
For RDS, the equivalent AWS-generated tag is aws:rds:primaryDBClusterArn — useful if you have multiple Aurora clusters and want per-cluster RDS breakdown without writing any code.
Why this matters
The default Cost Explorer view is dangerous in multi-tenant or multi-service architectures because it makes one large number look like one workload. Without per-cluster, per-service, or per-tenant breakdown:
- You can't tell which tenant grew 40% last month.
- You can't ROI a cluster consolidation.
- You can't bill internal teams for the infra they consume.
- You can't catch a runaway task silently doubling your compute spend.
The fix is two settings in one account and a day's wait. There is no excuse for shipping a Fargate workload without it.
TL;DR
- Activate
aws:ecs:clusterNameandaws:ecs:serviceNamein Cost Allocation Tags (payer account). - Enable Split Cost Allocation Data for ECS in Cost Management Preferences (payer account).
- Click Backfill tags if you want history.
- Wait 24 hours.
-
--group-by Type=TAG,Key=aws:ecs:clusterNamein Cost Explorer, or query CUR 2.0 directly.
The first step is in the AWS docs. The second is the one you need.
Originally published on khimananda.com.
If this saved you an afternoon, share it with your platform team. What's the weirdest billing surprise you've debugged in AWS? Drop it in the comments — I'm collecting them.
Top comments (0)