Skip to the content.

Terraform Pattern: Using count and count.index to create multiple custom azure policy definitions

Problem Statement

Steps

  1. Define a variable list containing tag keys
  2. Create a resource multiple times based on the length of the variable list
  3. Reference all values from the variable list using [count.index]

1 - Define a variable list containing tag keys

First, within your policy definition module, define a variable list containing your tag keys.

variable "mandatory_tag_keys" {
  type        = list
  description = "List of mandatory tag keys used by policies 'addTagToRG','inheritTagFromRG','bulkAddTagsToRG','bulkInheritTagsFromRG'"
  default = [
    "Application",
    "CostCentre",
    "Environment",
    "ManagedBy",
    "OwnedBy",
    "SupportBy"
  ]
}

2 - Create a resource multiple times based on the length of the variable list

Next, within your policy definition resource block, you can reference your variable list using count = length(var.variableName).

This will create your policy definition resource multiple times based on the length of your variable list.

So for example, if you have 6 tag keys defined in your variable list, your policy definition resource will be created 6 times.

resource "azurerm_policy_definition" "addTagToRG" {
  count = length(var.mandatory_tag_keys)

3 - Reference all values from the variable list using [count.index]

Finally, also within the policy definition resource block, you can reference your variable list values using ${var.variableName[count.index]}.

Using ${var.variableName[count.index]} means the index of tag keys contained in your variable list can be referenced for each policy definition resource created.

Specific variable index items can also be referenced using ${var.variableName[0]},${var.variableName[1]},${var.variableName[2]}, etc.

  name         = "addTagToRG_${var.mandatory_tag_keys[count.index]}"
  policy_type  = "Custom"
  mode         = "All"
  display_name = "Add tag ${var.mandatory_tag_keys[count.index]} to resource group"
  description  = "Adds the mandatory tag key ${var.mandatory_tag_keys[count.index]} when any resource group missing this tag is created or updated. \nExisting resource groups can be remediated by triggering a remediation task.\nIf the tag exists with a different value it will not be changed."
  metadata = jsonencode(
    {
    "category": "${var.policy_definition_category}",
    "version" : "1.0.0"
    }
)
  policy_rule = jsonencode(
    {
        "if": {
          "allOf": [
            {
              "field": "type",
              "equals": "Microsoft.Resources/subscriptions/resourceGroups"
            },
            {
              "field": "[concat('tags[', parameters('tagName'), ']')]",
              "exists": "false"
            }
          ]
        },
        "then": {
          "effect": "modify",
          "details": {
            "roleDefinitionIds": [
              "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
            ],
            "operations": [
              {
                "operation": "add",
                "field": "[concat('tags[', parameters('tagName'), ']')]",
                "value": "[parameters('tagValue')]"
              }
            ]
          }
        }
  }
)
  parameters = jsonencode(
    {
        "tagName": {
          "type": "String",
          "metadata": {
            "displayName": "Mandatory Tag ${var.mandatory_tag_keys[count.index]}",
            "description": "Name of the tag, such as ${var.mandatory_tag_keys[count.index]}"
          },
          "defaultValue": "${var.mandatory_tag_keys[count.index]}"
        },
        "tagValue": {
          "type": "String",
          "metadata": {
            "displayName": "Tag Value '${var.mandatory_tag_value}'",
            "description": "Value of the tag, such as '${var.mandatory_tag_value}'"
          },
          "defaultValue": "'${var.mandatory_tag_value}'"
        }
  }
)
}

Home

azure-policy-as-code