Every January I run into the same mess in Azure environments. Tags are missing or inconsistent, cost centers no longer match reality, and a fair number of resources have owners nobody can identify. Most organizations start with good intentions, but if nobody actively enforces tag governance, things drift, and the drift speeds up once new projects and budgets get going. Azure Policy tags make it much easier to standardize tags, fix old resources and keep costs under real control, as long as you set them up properly.

Two built-in policies handle inheritance and required tags at scale

The two built-in policies I use most are "Inherit a tag from the resource group if missing" (inheritance) and "Require a tag on resource groups" (enforcement). Both come with "Modify" or "Deny" effects. "Deny" blocks new resources when a required tag is missing. "Modify" can add tags automatically or correct values, but only if a managed identity is assigned to the policy. In client projects I always assign these policies at the management group level, which covers every subscription and resource group, including the ones that get created later. Inheritance saves a lot of grumbling, because most teams hate tagging each resource by hand. The setup details are in Microsoft's documentation on tag inheritance.

If you roll these policies out to an environment that already has resources, you need remediation. In the Azure portal (Policy → Remediation) you can start remediation tasks that add missing tags to existing resources. Here too you need the "Modify" effect and a managed identity with write permissions. Microsoft walks through it in the official remediation how-to.

A small set of enforced tags works better than a long list

I've watched companies try to introduce a dozen tags on day one, and in practice that almost never works. What does work is a short list of tags that is strictly enforced everywhere. For most environments I recommend:

  • costcenter
  • owner
  • environment (e.g., prod, dev, test)

With these three you get clear billing, a named person responsible for each resource and control over the lifecycle. They are also easy to automate and check. If you later need project names or data classification, you can add them one at a time. Microsoft's Azure Policy tag tutorial has more recommendations.

Pro tip: For modify/inherit policies, I always create a dedicated managed identity at the management group level with Contributor permissions. That way you don't run into permission errors when the remediation tasks run.

Cost Management tag inheritance does not replace policy enforcement

This one catches people out: not every tag you apply in Azure appears in cost reports by default. Cost Management has its own "Tag inheritance" feature (Azure portal → Cost Management → Settings → Tag inheritance), which copies tags from the resource group to its resources for reporting. That helps in older, inconsistent environments, but it is no substitute for tags enforced by policy. Policies enforce tags technically. Tag inheritance in Cost Management only affects reporting, so it does nothing for you if automation or access control depends on the tags.

Remediation cleans up the resources that existed before the policies

Policies on their own won't fix years of resource sprawl. So after introducing new tag policies I always run remediation as well. In the Azure portal, go to Policy → Remediation and start a remediation task for each policy. Again, this only works with the "Modify" effect and a managed identity. In large tenants it can take a while, but you need that clean, compliant baseline before cost analysis and governance mean anything.

A KQL query in Resource Graph shows where tags are still missing

My go-to tool for finding untagged resources is Azure Resource Graph Explorer (Azure portal → Resource Graph Explorer). With Reader rights on the subscriptions, run this short KQL query:

// Azure Resource Graph Explorer
Resources
| where isnull(tags["costcenter"]) or isnull(tags["owner"]) or isnull(tags["environment"])
| project name, type, resourceGroup, subscriptionId

It lists every resource that is missing at least one of the three key tags. I use it to check progress after rolling out policies and remediation, and to see where there's still cleanup to do.

The diagram below shows how inheritance, enforcement and remediation fit together across management groups, resource groups and resources:

flowchart TD
MG["Management Group"] --> P1["Policy: inherit tag"]
P1 --> RG["Resource Group"]
RG --> P2["Policy: require tag"]
P2 --> Res["Resource"]
Res --> Rem["Remediation"]

Figure: How tagging policies and remediation interact across management group, resource group and resources

I keep tags minimal and enforce them everywhere

The approach that works for me is simple. Pick a small set of tags that actually mean something, enforce them technically and remediate everything that already exists. With Azure Policy tags I've seen tenants go from a mess to a clear picture in days rather than weeks. Assign the policies at management group scope, run remediation, and treat Cost Management tag inheritance as an extra reporting aid, not a crutch. Do that and you start the new budget year with clean cost data you can trust, and far fewer headaches when reporting comes around.