Designing Tagging Strategy for Microsoft Azure - Part 4 - Enforcing Tags at the Resource Group level and Inheriting on underlying resources

@20aman    Oct 10, 2021

This blog is a part of the Designing Tagging Strategy for Microsoft Azure series. You can find the Index of this series here: Designing Tagging Strategy for Microsoft Azure.

In the last post, we looked at enforcing the tags at the subscription level and inheriting those at the resource level. In this post, we are looking at policies and various nuances in implementing the third strategy i.e. enforcing tags at the Resource Group level and inheriting at each resource.

Require Tags on a Resource Group

You can require tags on a Resource Group by using the below Azure policy. This is an extension of the in-built policies. This extends the policy to leverage multiple tags in a single policy.

The below policy is enforcing the ApplicationOwner and DepartmentName tags on the Resource Groups. It denies the creation of Resource Groups if any one of the tag is not present.

Note: You can parameterize the tag name and its value as well very easily. You can check in-built policies for reference. Or let me know if this is something you want to see and I can create a parameterized sample.

"policyRule": {
  "if": {
    "allOf": [
      {
        "field": "type",
        "equals": "Microsoft.Resources/subscriptions/resourceGroups"
      },
      {
        "anyOf": [
          {
            "field": "tags['ApplicationOwner']",
            "exists": "false"
          },
          {
            "field": "tags['DepartmentName']",
            "exists": "false"
          }
        ]
      }
    ]
  },
  "then": {
    "effect": "deny"
  }
}

You will get an error similar to below when trying to create a resource group after you have defined and assigned this policy in your subscription.

Resource Group creation error due to tagging policy

When you get the above error after trying to create the Resource Group without tags (if you have the policy assigned already to enforce tags on RGs), then click on line #1 in the screenshot. In the pop-up blade that opens up, click on "Raw Error" as shown above as #2. Then scroll down to see the details of the policy that stopped the resource group creation.

Inheriting Tags from Resource Groups

You can easily inherit the tags from a Resource Group down to its underlying resources by using an Azure policy specifically for this purpose. You have three approaches for inheriting the tags from the resource group level:

  1. Inherit the tags and their value only if this tag is missing from the resource
  2. Inherit and replace the tag if it doesn't match the value of the same tag at the resource group level
  3. Inheriting the tags regardless of what is specified at the resource level

Which approach works for you depends on your requirements. The first two approaches are identical to what we discussed in the last post for the subscription level. You can view those at this link and just replace subscription with resource group level functions: Enforcing Tags at the Subscription level and Inheriting on underlying resources.

We have seen approach 3 being the most common and we will discuss that next.

Inheriting the tags regardless of what is specified at the resource level

In the below policy, you check that all of the below conditions should be met before the action can be taken:

  • The ApplicationOwner and DepartmentName tags exist at the resource group level
  • Both of these tags does not have an empty value at the resource group level

If both of these conditions are true then the "modify" effect is applied. Within this effect, the tags from the resource group level are applied at the resource level.

Note: You can parameterize any values within this sample policy. Also, you can extend this policy to multiple tags (without creating additional policies).

"policyRule": {
  "if": {
    "allOf": [
      {
        "value": "[resourceGroup().tags['ApplicationOwner']]",
        "exists": "true"
      },
      {
        "value": "[resourceGroup().tags['ApplicationOwner']]",
        "notEquals": ""
      },
      {
        "value": "[resourceGroup().tags['DepartmentName']]",
        "exists": "true"
      },
      {
        "value": "[resourceGroup().tags['DepartmentName']]",
        "notEquals": ""
      }
    ]
  },
  "then": {
    "effect": "modify",
    "details": {
      "roleDefinitionIds": [
        "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
      ],
      "operations": [
        {
          "operation": "addOrReplace",
          "field": "tags['ApplicationOwner']",
          "value": "[resourceGroup().tags['ApplicationOwner']]"
        },
        {
          "operation": "addOrReplace",
          "field": "tags['DepartmentName']",
          "value": "[resourceGroup().tags['DepartmentName']]"
        }
      ]
    }
  }
}

Complete Policy Samples on GitHub

You can find the complete policy samples on the GitHub in my policy samples repository here: AzurePolicySamples - Tagging.





Comments powered by Disqus