Adjusting Azure tagging policies

Failed certificate error in Azure

App Service Managed Certificates are one of the many wonders of the Azure world. No messing around with Lets Encrypt, just prove to Azure that you own the domain (via a TXT record) and free, rotating, certificates can be yours with a couple of clicks.

We use them for HTTPS on our 301 Redirect function I wrote about previously. Adding a domain this week I received the above error. Of course the “click for more details” didn’t work so, for a day or two, I was in the dark.

Then a colleague reached out and said they were having trouble creating alerts: the lightbulb went off. We recently added the Require a tag on resources policy to our subscription to ensure that all new resources are tagged by utilization - thereby permitting better cost allocation across business units.

The issue, with alerts and certs, is that neither of these resource types support tagging. Betting that the anonymous error was a result of the policy, I temporarily disabled it and was able to create the certificate, avoiding a support call to Microsoft.

But how to get the policy to work correctly? The solution was to clone the built in policy and add exceptions for resources we’re using that don’t support tagging. Here’s the policy in full:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{
  "properties": {
    "displayName": "Require a tag on tagable resources (excluding alerts and certs)",
    "policyType": "Custom",
    "mode": "Indexed",
    "description": "Enforces existence of a tag. Does not apply to resource groups. Excludes alerts and certs.",
    "metadata": {
      "category": "Tags",
      "createdBy": "GUID,
      "createdOn": "2020-12-22T17:28:35.0617296Z",
      "updatedBy": null,
      "updatedOn": null
    },
    "parameters": {
      "tagName": {
        "type": "String",
        "metadata": {
          "displayName": "Tag Name",
          "description": "Name of the tag, such as 'Usage'"
        }
      }
    },
    "policyRule": {
      "if": {
        "allOf": [
          {
            "field": "[concat('tags[', parameters('tagName'), ']')]",
            "exists": "false"
          },
          {
            "field": "type",
            "notIn": [
              "Microsoft.Web/certificates",
              "Microsoft.Insights/metricalerts",
              "microsoft.insights/actionGroups",
              "microsoft.alertsmanagement/smartdetectoralertrules"
            ]
          }
        ]
      },
      "then": {
        "effect": "deny"
      }
    }
  },
  "id": "/subscriptions/GUID/providers/Microsoft.Authorization/policyDefinitions/GUID",
  "type": "Microsoft.Authorization/policyDefinitions",
  "name": "GUID"
}

I’ve highlighted the key lines, starting at 24. Essentially the policy does an and of

A quick way to find applicable resource types is to look for any resources failing the policy check and copy/paste their type in.

Pretty easy once you figure it out. I hope you find it useful.