Automatic tagging for Azure resources

Automatic tagging for Azure resources

To tag or not to tag 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, REST API and the portal, of course. Almost all resource types support tags. However, you should take into 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 modifying 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 balanced approach is to demand 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 technique 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 allow 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., the 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 multiple people are involved in project development or service operation, such “benefits” might not be 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, you get configuration B. All the beauty of declarative syntax goes to hell.

Another example of automation doing more harm than adding value is using Azure Policies to automatically tag resources with some default values. When used unintentionally, 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 remember that “with great power comes great responsibility.” If you want to create some automation based on your tags, think carefully about the side effects.

Also, my Azure Policy repository on GitHub contains sample ARM templates for Azure Policy definitions that enforce or inherit tags.