Using Custom Azure Policies to Enforce Tagging of Resources
Sourav Bera
Solution Architect @Microsoft, Microsoft Intern FY'22, Judge/Speaker/Mentor, 4 ? CodeChef, Pupil at Codeforces, SIH Winner, SOH Winner, Postman Leader CKA, CKAD, CKS, LFCS IEEE Leadership Summit, Kubestronaut Program
Tagging resources in Azure is an essential aspect of resource governance and managing your resources. It helps you to identify, organize, and search for resources based on their attributes. However, enforcing tagging rules and conventions can be a challenging task, especially when you have a large number of resources and a large number of teams in different organizations provisioning those resources.
Azure Policy provides a solution to this problem by allowing you to enforce tagging rules and conventions across your organization. By creating a policy, you can ensure that resources are deployed to your subscription with the expected tags for your organization. This helps you to avoid the scenario of resources being deployed without the required tags or searching for resources that aren’t compliant.
Here are some steps to follow when using Azure policy to enforce tagging of resources:
Now the question is how we achieve this, well for this you might find various approach available to enforce tagging of resources. I am encapsulating the Industry standard policy definitions that you can use to enforce tagging via policy and remediate the existing resources.
Require tags on Resources/Resource Groups: (Github)
{
"properties": {
"displayName": "Require multiple tags on resource groups",
"policyType": "BuiltIn",
"mode": "All",
"description": "Enforces existence of multiple tags on resource groups.",
"metadata": {
"version": "1.0.0",
"category": "Tags"
},
"parameters": {
"tagName1": {
"type": "String",
"metadata": {
"displayName": "Tag Name 1",
"description": "Name of the first tag, such as 'environment'"
}
},
"tagName2": {
"type": "String",
"metadata": {
"displayName": "Tag Name 2",
"description": "Name of the second tag, such as 'costCenter'"
}
}
},
"policyRule": {
"if": {
"allOf": [
{ //remove this block in case of resources
"field": "type",
"equals": "Microsoft.Resources/subscriptions/resourceGroups"
},
{
"field": "[concat('tags[', parameters('tagName1'), ']')]",
"exists": "false"
},
{
"field": "[concat('tags[', parameters('tagName2'), ']')]",
"exists": "false"
}
]
},
"then": {
"effect": "deny"
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/12345678-1234-1234-1234-123456789012",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "12345678-1234-1234-1234-123456789012"
}
The following Json policy definition takes two parameters i.e. tag name (you can add many tag name required) and checks if the resources created contains the required tags if not 'deny' the resource creation.
Require multiple tag names and values from Set: (Github)
Enforce this policy if you want to limit the user from creating ambiguous tag names and value sets for your resources.
{
"mode": "Indexed",
"policyRule": {
"if": {
"allOf": [
{
"not": {
"field": "[concat('tags[', parameters('tagName1'), ']')]",
"in": "[parameters('tagValue1')]"
}
},
{
"not": {
"field": "[concat('tags[', parameters('tagName2'), ']')]",
"in": "[parameters('tagValue2')]"
}
}
]
},
"then": {
"effect": "deny"
}
},
"parameters": {
"tagName1": {
"type": "String",
"metadata": {
"displayName": "Tag Name 1",
"description": "Name of the first tag, such as 'environment'"
}
},
"tagValue1": {
"type": "Array",
"metadata": {
"displayName": "Tag Value 1",
"description": "Value of the first tag, such as 'production'"
},
"allowedValues": [
"Dev",
"Test",
"Prod"
]
},
"tagName2": {
"type": "String",
"metadata": {
"displayName": "Tag Name 2",
"description": "Name of the second tag, such as 'region'"
}
},
"tagValue2": {
"type": "Array",
"metadata": {
"displayName": "Tag Value 2",
"description": "Value of the second tag, such as 'eastus', etc."
},
"allowedValues": [
"eastus",
"centralIndia",
"westus"
]
}
}
}
the above Json policy definition for takes two parameters, tag keys, you can allow as many tags and value list required. The policy only allows you to create resources with required tag key and values set specified.
Inherit tags and values from Resource Groups: (Github)
{
"properties": {
"displayName": "Inherit a tag from the resource group",
"policyType": "BuiltIn",
"mode": "Indexed",
"description": "Adds or replaces the specified tag and value from the parent resource group when any resource is created or updated. Existing resources can be remediated by triggering a remediation task.",
"metadata": {
"version": "1.0.0",
"category": "Tags"
},
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"displayName": "Tag Name",
"description": "Name of the tag, such as 'environment'"
}
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "[concat('tags[', parameters('tagName'), ']')]",
"notEquals": "[resourceGroup().tags[parameters('tagName')]]"
},
{
"value": "[resourceGroup().tags[parameters('tagName')]]",
"notEquals": ""
}
]
},
"then": {
"effect": "modify",
"details": {
"roleDefinitionIds": [
"/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
],
"operations": [
{
"operation": "addOrReplace",
"field": "[concat('tags[', parameters('tagName'), ']')]",
"value": "[resourceGroup().tags[parameters('tagName')]]"
}
]
}
}
}
},
"id": "/providers/Microsoft.Authorization/policyDefinitions/cd3aa116-8754-49c9-a813-ad46512ece54",
"type": "Microsoft.Authorization/policyDefinitions",
"name": "cd3aa116-8754-49c9-a813-ad46512ece54"
}
The above Json policy definition checks if the resources in the RGs are tagged with a specified tag key or not (which is likely to be present in RG tags), if the tag is not present that it inherits the tags from RGs. Similar implementation for inheriting tags from subscriptions if missing.
By following these steps, you can ensure that your resources are tagged correctly and consistently across your organization. This helps you to organize and manage your resources effectively.
Infrastructure Engineer
1 年Hi, is there any way i can get list of all untagged resources in a subscription
Solution Architect @Microsoft, Microsoft Intern FY'22, Judge/Speaker/Mentor, 4 ? CodeChef, Pupil at Codeforces, SIH Winner, SOH Winner, Postman Leader CKA, CKAD, CKS, LFCS IEEE Leadership Summit, Kubestronaut Program
1 年Do let me know if you find this blog helpful, let me know on what other topics would you like me to create new blogs.