A strategy for resource tagging within Azure can often become an afterthought. While you might have a plan in place for what tags to apply, the controls to ensure consistent application of these tags can slip through the cracks, and you can soon be down the road with hundreds or even thousands of resources. This is a common scenario we have encountered. Clients recognise the importance of tagging and reach a point where they want to leverage tags to enhance reporting, provide insight and support informed decision making.
Policy enforcement?
The first idea can often be to leverage policy enforcement to ensure that resource groups or resources have the required tags at creation (or deny the creation). This has some pitfalls:
- Policy is applied on an attempted 'write' of the resource or resource group, which can include even minor changes, so not just those that are newly created
- Some resource groups (and resources) are created automatically for certain things, Azure backup, network watcher, resource mover, cloud shell, Kubernetes management - deny enforcement could prevent these from successfully creating
- The standard built-in policies can mandate a tag but not a value, so you can end up with tags existing with blank values where others may be unsure of which tag to use
- You might have your own automations that create or modify resources that get stopped in their tracks
So the intention of policy enforcement, while good, could cause a great deal of disruption.
What next?
We've worked through some of these challenges and think that we have a reasonable solution to get a starter strategy implemented and fix the majority of retrospective tagging.
In a nutshell, we configure tags that can be audited by policy for compliance against resource groups (audit as required, but not enforced). Another policy audits for allowed values for some of those tags. Additionally, inherit tag from resource group policy assignments are implemented for each tag that requires to be inherited.
The following diagram shows tags for Department, Environment, Lifecycle, Owner and Purpose as mandatory on Resource Groups.
These are a minimum easy-fit suggestion that should be easy to populate for all resource groups. You can have more granular tags, but it's important that all tags can be populated with values for all resource groups.
Most of those tags are then inherited down to resources within the resource groups.
Fix up existing resource group tags
We've developed a solution to tackle the backlog of tags that are missing from resource groups. Azure Policy is still used to remediate the inheritance of tags to resources from the resource group. As part of onboarding to our Azure Managed Service, we have a monitoring resource group deployment that contains some event driven automations.
A CSV file export of resource groups, including tags, can be obtained from the Azure Portal. However, the format of the data is not very usable within Excel. The first automation is triggered when the CSV file is uploaded into the designated container within the monitoring resource group storage account. This converts the CSV file into a more Excel friendly XLSX file providing a column per tag that can be easily edited to fill in the blanks of missing tag values.
Once ready, the updated XLSX file can be uploaded to another designated storage container. This triggers an automation to apply a merge of the tags from within the file to resource groups. This is achieved requiring only the 'Tag Contributor' role, so the automation uses least possible access.
The following image shows a shortened sequence of an XLSX file populated with tags and values being uploaded to the storage account which triggers the automation. The Azure Portal is then showed being refreshed after a couple of minutes showing the tags have updated against the resource groups.
One of the key aims of our Azure Managed Service is about supporting how clients operate at scale within Azure, leveraging native capabilities where possible.