Search code examples
azureazure-policy

Checking that old and new ressources are configured with a tag with specific case


Hello community 🙋‍♂️!

I'm configuring an Azure Policy to check presence of a tag on new and old ressources.

Checking the presence only was quite easy:

 policy_rule = <<RULE
  {
    "if": {
          "allOf": [
            {
              "field": "type",
              "equals": "Microsoft.Resources/subscriptions/resourceGroups"
            },
            {
              "field": "[concat('tags[', parameters('TagName'), ']')]",
              "exists": "false"
            }
          ]
        },
        "then": {
          "effect": "[parameters('effect')]"
        }
  }
  RULE

With following parameters:

parameters = <<PARAMETERS
 {
        "tagName": {
          "type": "String",
          "metadata": {
            "displayName": "Tag Name",
            "description": "Name of the tag, such as 'environment'"
          }
        },
        "effect": {
          "type": "String",
          "defaultValue": "Audit",
          "allowedValues": [
            "Audit",
            "Deny",
            "Disabled"
          ],
          "metadata": {
            "displayName": "Effect",
            "description": "The effect determines what happens when the policy rule is evaluated to match"
          }
        }
  }
PARAMETERS

But now I want that the policy rule also checks the case of the tagName parameters.

Ex: guess expected tagName is RigorousMakeMeHappy. Then, I want that ressources be configured with RigorousMakeMeHappy but not with rigorousmakemehappy or rigorousMakeMeHappy or RIGOROUSMAKEMEHAPPY etc.

And I struggled two days w/o success.

I tried, among others things, the following:

  policy_rule = <<RULE
  {
    "if": {
          "anyOf": [
            {
            "field": "tags",
            "match": "[parameters('tagName')]"
            }
          ]
        },
        "then": {
          "effect": "[parameters('effect')]"
        }
  }
  RULE

I tried to achieve with following documentations:

Thanks for your precious help !

EDIT: @SiddheshDesai

I should be more specific, I want ONLY the Key matching case sensitive my pattern:

With this code:

  policy_rule = <<RULE
  {
    "if": {
          "allOf": [
            {
            "not": {
               "field": "[concat('tags[', parameters('tagName'), ']')]",
              "match": "[parameters('tagName')]"
             }
            },
             {
              "field": "type",
              "equals": "Microsoft.Compute/virtualMachines"
            }
          ]
        },
        "then": {
          "effect": "[parameters('effect')]"
        }
  }

It's not working:

Create VM with Tag RigorousMakeMeHappy and value qsdsqfsdf

And result is:

Validation not OK because we are trying to match the value of the KV pair

If I change the tag in this way:

Create VM with Tag RigorousMakeMeHappy and value RigorousMakeMeHappy

Result is:

Validation OK because we are matching the value of the KV pair


Solution

    • EDIT: I improved first solution to fix case where you have the pattenr RigorousMakesMeHappywhateveryouaddtomatchingpattern

    @SiddheshDesai: I've found the answer (or one of... but honestly I think it's the only one 😄) and, again, thanks for your time!

    Here is the code:

    policy_rule = <<RULE
      {
        "if": {
              "allOf": [
                {
                  "field": "type",
                  "equals": "Microsoft.Compute/virtualMachines"
                },
                {
                "anyOf": [
                  {
                     "value": "[contains(string(field('tags')),parameters('backupTagName'))]",
                     "notMatch": "True" 
                  },
                  {
                     "field": "[concat('tags[', parameters('backupTagName'), ']')]",
                     "exists": "false"
                  }
                ]
                }
              ]
            },
            "then": {
              "effect": "[parameters('effect')]"
            }
      }
      RULE
    

    Then, if you tagName is RigorousMakesMeHappy and whatever the tagValue is you will be compliant or not with:

    • RigorousMakesMeHappy: ✅ (compliant)
    • RigorousMakesMeHappywhateveryouaddtomatchingpattern:❌ (not compliant)
    • rigorousMakesMeHappy: ❌
    • RigorousMakesMeHapPY: ❌
    • qsdfqsdfqsfd: ❌
    • yougettheidea: ❌