I used to think tagging was easy.

The first time I was involved in setting up a tagging strategy was during a migration to AWS. This was great because it meant that we could define what tags we wanted from the beginning, and there weren’t hundreds of inconsistently-tagged resources already in our environment (or at least not too many). There was also a conversation going about how we wanted to enforce them.

I realise now how easy I had it.

Most of the time, you’re not handed a clean slate to start from. There are missing tags, inconsistent tags (”prod” vs “Prod”), and tags attributing things to teams that don’t exist anymore.

So here's how to set up a tagging strategy that survives contact with reality, even if your AWS environment is a mess.

Start with a minimal, non-negotiable set of tags

You might have the urge to start adding as many tags as possible, but please, fight it.

Being ambitious here doesn’t pay. Pick 4-6 tags that actually help decisions get made. If you can't name a specific action someone might take because of this tag's value (e.g. shutting down a resource, triggering an alert), don’t include it.

The right tags for you depend on your setup, but here are some to consider:

  • CostCenter or BusinessUnit — who pays

  • Environment (prod/staging/dev)

  • Owner or Team — who to email when something gets expensive

  • Application or Service — what it's for

  • ManagedBy (terraform/console/cloudformation)

You want the tagging strategy to be easily adopted, and a strategy with 5 tags has a much higher chance of that than a strategy with 15.

One more step before you move on: activate each of these as a cost allocation tag in Billing and Cost Management. If you skip this none of it will show up in Cost Explorer or your Cost and Usage Report.

Tackle the mess in two tracks

There are two things going on here, new resources getting created, and resources that are already sitting there with incomplete or inconsistent tagging. So let’s split the tasks.

Track A: New Resources

Every untagged resource created today is something you will have to fix later, so make sure new resources have tagging enforced at creation time.

The best way is to rely on more than one strategy.

As a base, use AWS Organizations Tag Policies to define the standard for allowed values (Prod or prod?).

This is a good start but it only reports tags that are non-compliant, it doesn’t enforce anything.

To enforce, you can use Service Control Policies (SCPs). They actively block resources with missing or non-compliant tags from being deployed, and can be really powerful.

Careful though, because they can be too powerful. Overuse them and you risk blocking deployment to a degree that gets engineers frustrated. Use them sparingly, scoped to resources that must be compliant, and only for your non-negotiable tags.

Another approach, if you use IaC, is to enforce tags in the Terraform module or CloudFormation template itself (as a required variable with no default). This way it fails before it even reaches AWS.

Now we’ve got new resources tagged nicely on creation. But what about the mess that’s already running?

Track B: Retroactively fix what exists.

This is the boring yet necessary part. We need to go back and tag resources that are already running.

It can seem like a huge mountain to climb, but don’t worry, there are a couple of things that make it easier.

First of all, use the AWS tag editor to bulk-tag by resource type, region, or existing partial tags. E.g. you can search for resources tagged with ‘Prod’, ‘prod’, and ‘production’, then bulk-tag them to whichever convention you settled on.

Secondly, stop focusing on getting 100% tagging coverage. There’s little value in chasing down resources that cost 5$ a month.

Instead, ask what % of your costs are attributable (e.g. to a project or team).

With this in mind, start by finding and tagging the most expensive resources in your environment. Tag the top 20% most expensive ones and you might find that closer to 80% of your cloud spend is now attributable. Then you can go chasing the rest if priorities allow.

Ok, so now we have existing resources tagged as we’re done, right?

Well, almost.

Automate the detection of untagged resources, and get people to pay attention

Sometimes you need more than a one-time tagging drive. Your AWS environment is not static, it’s constantly changing, and sometimes tags get changed and thing slips through the cracks.

The fastest way to get some automation running without writing custom code is to use AWS Config's required-tags managed rule. It scans your environment and notifies you if a resource is non-compliant.

Again, be careful of noise here. With too many notifications for untagged resources, people will stop paying attention. Send a summary, not an alert for every single thing that changes in real time. Or give teams a list of things that changed in the past week only.

Track the numbers

Pick one metric, e.g. the percentage of your AWS spend attributed to a team or project. Check it this month, then every month after that. The important thing is that the number is increasing so you know it’s working.

So tagging may not be easy, but I hope this has made it slightly more manageable.