To tag or not to tag, that is out of the question. The question is how to apply tags to Azure resources only when needed and do that efficiently.

Azure tags are just metadata information about resources, which allows you to classify and logically group them. Tags can be created via ARM templates, Azure PowerShell, Azure CLI and, REST API and the portal, of course. Almost all resource types support tags. However, you should take in to account some generic limitations.

Common issues with Azure metadata tags

The most common issues with using Azure Tags are either not using them at all or going from one extreme to another – applying dozens of them to every resource. In the first case, you are missing an opportunity to organize and manage your resources more effectively. In the second, you add unnecessary overhead for managing all those tags that don’t provide you with any real value.

To make it worse, some organizations enforce mandatory tagging for all Azure resources, so you cannot create or modify an existing resource if it doesn’t have a specific tag(s). Sure, there should be some governance for your Azure subscriptions that keeps your infrastructure neat and structured, but when it goes to an extreme, you might need to spend hundreds of additional hours to modify your ARM templates or deployment scripts to have these mandatory tags encoded in them.

When people don’t see any value for them in doing some dumb job like adding those 50+ tags to their code, they tend to look for shortcuts. For example, copy and paste the same code fragment with tags to all files or autogenerate tags with some fake values. In the meantime, you might be unpleasantly surprised that most resources in your subscription(s) have dummy tags that don’t help you to operate those resources in any way but obscure really valuable information.

All about trade-offs

The key thing to remember is that there is no single best solution for all possible cases. Each tagging strategy has its pros and cons, so you have to make trade offs between simplicity and accuracy.

For example, one of the balanced approaches is to demand an appropriate tagging at the resource group level. As resource groups serve as a logical boundary for a group of resources that share a common life cycle, you can apply tags to these logical entities rather than to individual resources. Implementing such a tagging technic will allow you to simplify your governance without introducing excessive controls.

For cases when it is more convenient to have tags at the resource level, you can implement automatic tag copying – basically inherit tags from the resource group level. Of course, in some scenarios, tags might have meaning only for a specific resource type, and you have to choose whether to tag a resource group and copy the tag to all containing resources or to tag some resources individually.

If you see that something is not working as expected or become cumbersome, don’t be afraid to change it to suit your needs.

When automation is harmful

With the introduction of new Azure Policy effects that allows you to modify resources during their deployment or run remediation tasks on existing resources, the temptation to automate resource configuration on the fly might be very strong. If I were you, I would think twice before creating Azure Policies that modify my resources. Let me illustrate why.

Imagine that you have a policy in your subscription that modifies resource configuration during the deployment based on some criteria, e.g., tag’s value or its presence in the original deployment template. Now, each time you deploy a resource that violates that policy, the configuration of that resource will be changed, so the resource is compliant. Sounds good, right? No really.

In real-world scenarios, when there are multiple people are involved in project development or service operation, such “benefits” might be not evident for all team members and cause unwanted system behavior, painful hours of debugging and confusion. You deploy configuration A, but due to some background automation gets a configuration B. All the beauty of declarative syntax goes to hell.

Another example when automation does more harm then adds value is the usage of Azure Policies to automatically tag resources with some default values. When used not deliberately, this approach might cause “tag hell” in your subscription(s), as I mentioned in the first section: lots of tags that mean nothing or have no use.

So, always keep in mind that “with great power comes great responsibility.” If you want to create some automation based on your tags, think carefully about side effects.

P.S. You can find sample ARM templates for Azure Policies that enforce or inherit tags in the following repository on GitHub.