Cost Allocation Tags
When your AWS (Amazon Web Services) bill is one big number, you cannot answer simple questions like “how much did the mobile team spend?” or “what does the staging environment cost us?”. Cost allocation tags solve this. A tag is just a key-value label (for example Team = mobile or Environment = prod) that you attach to resources, and a cost allocation tag is a tag you have told AWS Billing to track on your bill. Once activated, AWS breaks your spend down by that tag in Cost Explorer and your billing reports, which is the foundation for chargeback (billing each team for what they used) and showback (just showing each team what they used).
Tagging vs cost allocation tags
These are two separate steps, and missing the second one is the most common mistake.
| Step | What it does | Where you do it |
|---|---|---|
| Tag the resource | Adds a key = value label to an EC2 instance, S3 bucket, etc. | Any service console, CLI, or IaC |
| Activate the tag | Tells Billing to split your cost data by that tag key | Billing console (one place, account-wide) |
Tagging a resource alone does nothing to your bill breakdown. You must also activate the tag key in Billing before it appears as a grouping dimension.
Two kinds of cost allocation tags
- User-defined tags are the ones you create, like
Project,Team,CostCenter, orEnvironment. You choose the keys and values. - AWS-generated tags are created automatically by AWS and always start with the prefix
aws:. The most useful one isaws:createdBy, which records who created a resource.
Both must be activated in Billing before they show up as a cost dimension.
When to use this (and when not to)
Use cost allocation tags whenever more than one team, project, or environment shares an account, or whenever finance asks “where is the money going?”. They are essential for chargeback/showback models.
You do not need them if you put every team in its own AWS account under AWS Organizations, because the account itself already separates the spend. In practice large companies use both: separate accounts for hard boundaries, and tags for finer slices inside each account.
The retroactive gotcha
Warning: Cost allocation tags are NOT retroactive. AWS only splits your costs by a tag key from the moment you activate that key in Billing. Past usage is never re-tagged, even if the resources already carried the tag. Activation also takes up to ~24 hours to start appearing in your reports.
The practical lesson: tag from day one, and activate the keys you care about early. Anything that was untagged when the cost was incurred lands in an unallocated / “(not tagged)” bucket that you can never attribute later.
Activating a tag
Console steps
- Sign in and open the Billing and Cost Management console.
- In the left navigation choose Cost allocation tags.
- You will see two tabs: User-defined cost allocation tags and AWS-generated cost allocation tags.
- Select the checkbox next to each tag key you want to track (for example
Team,Project,Environment). - Choose Activate.
- Wait up to 24 hours, then check Cost Explorer — the tag key now appears as a grouping option.
Note: A user-defined tag key only shows up in this list after at least one resource in the account has been tagged with that key. If you do not see
Teamyet, tag a resource first.
AWS CLI
List the tags AWS knows about and their status:
aws ce list-cost-allocation-tags --status Inactive
Output:
{
"CostAllocationTags": [
{ "TagKey": "Team", "Type": "UserDefined", "Status": "Inactive" },
{ "TagKey": "Project", "Type": "UserDefined", "Status": "Inactive" },
{ "TagKey": "aws:createdBy", "Type": "AWSGenerated", "Status": "Inactive" }
]
}
Activate the keys you want:
aws ce update-cost-allocation-tags-status \
--cost-allocation-tags-status \
TagKey=Team,Status=Active \
TagKey=Project,Status=Active \
TagKey=aws:createdBy,Status=Active
Output:
{
"Errors": []
}
An empty Errors array means all the keys were activated successfully.
Tagging a resource
You activate a key once, but every resource still needs the tag applied. Here is how to tag an existing EC2 (Elastic Compute Cloud) instance.
Console steps
- Open the EC2 console and select your instance (for example
i-0a1b2c3d4e5f). - Choose the Tags tab, then Manage tags.
- Choose Add tag, enter Key
Teamand Valuemobile, and Save.
AWS CLI
aws ec2 create-tags \
--resources i-0a1b2c3d4e5f \
--tags Key=Team,Value=mobile Key=Environment,Value=prod
This command prints no output on success.
Enforce tags with infrastructure as code
The cleanest way to guarantee tags is to bake them into your templates so nothing is created untagged. Terraform example:
resource "aws_instance" "api" {
ami = "ami-0abcdef1234567890"
instance_type = "t3.micro"
tags = {
Team = "mobile"
Project = "checkout"
Environment = "prod"
}
}
Enforcing a tagging policy
Manual tagging always drifts, so enforce it. Two complementary tools:
| Tool | What it does | Best for |
|---|---|---|
| Tag Policies (AWS Organizations) | Define allowed keys/values org-wide; report non-compliant resources | Standardizing tag spelling across accounts |
| Service Control Policies (SCPs) | Deny creating a resource unless a required tag is present | Hard-blocking untagged resources |
| AWS Config | Continuously audit and flag resources missing required tags | Detecting and remediating drift |
An SCP that blocks launching an EC2 instance without a Team tag looks like this:
Version: "2012-10-17"
Statement:
- Sid: DenyRunInstancesWithoutTeamTag
Effect: Deny
Action: "ec2:RunInstances"
Resource: "arn:aws:ec2:*:*:instance/*"
Condition:
"Null":
"aws:RequestTag/Team": "true"
Cost note: Activating cost allocation tags is free, and so is tagging resources. You only pay if you store detailed billing data — the legacy Cost and Usage Report (CUR) delivered to Amazon S3 costs only normal S3 storage (a few cents per GB per month for small reports).
Best practices
- Decide on a small, fixed set of mandatory keys (for example
Team,Project,Environment,CostCenter) and write them down before anyone launches resources. - Activate those keys in Billing on day one, since activation is not retroactive and takes ~24 hours.
- Standardize values too —
prodandProductioncount as different values and will split your reports. - Enforce tags with an SCP (deny untagged creation) plus AWS Config (catch drift), not just good intentions.
- Bake tags into CloudFormation or Terraform so resources are never created untagged.
- Review the unallocated “(not tagged)” bucket in Cost Explorer regularly and drive it toward zero.
- Activate the
aws:createdByAWS-generated tag for an easy audit trail of who launched what.