Apply resource policies for tags

This topic provides common policy rules you can apply to ensure consistent use of tags on resources.

Applying a tag policy to a resource group or subscription with existing resources does not retroactively apply the policy to those resources. To enforce the policies on those resources, trigger an update to the existing resources, as shown in Trigger updates to existing resources.

Ensure all resources in a resource group have a tag/value

A common requirement is that all resources in a resource group have a particular tag and value. This requirement is often needed to track costs by department. The following conditions must be met:

  • The required tag and value are appended to new and updated resources that do not have any existing tags.
  • The required tag and value are appended to new and updated resources that have other tags, but not the required tag and value.
  • The required tag and value cannot be removed from any existing resources.

You accomplish this requirement by applying to a resource group the following three policies:

Append tag

The following policy rule appends costCenter tag with a predefined value when no tags are present:

{
  "if": {
    "field": "tags",
    "exists": "false"
  },
  "then": {
    "effect": "append",
    "details": [
      {
        "field": "tags",
        "value": {"costCenter":"myDepartment" }
      }
    ]
  }
}

Append tag with other tags

The following policy rule appends costCenter tag with a predefined value when tags are present, but the costCenter tag is not defined:

{
  "if": {
    "allOf": [
      {
        "field": "tags",
        "exists": "true"
      },
      {
        "field": "tags.costCenter",
        "exists": "false"
      }
    ]
  },
  "then": {
    "effect": "append",
    "details": [
      {
        "field": "tags.costCenter",
        "value": "myDepartment"
      }
    ]
  }
}

Require tag and value

The following policy rule denies update or creation of resources that do not have the costCenter tag assigned to the predefined value.

{
  "if": {
    "not": {
      "field": "tags.costCenter",
      "equals": "myDepartment"
    }
  },
  "then": {
    "effect": "deny"
  }
}

Require tags for a resource type

The following example shows how to nest logical operators to require an application tag for only a specified resource type (in this case, storage accounts).

{
    "if": {
        "allOf": [
          {
            "not": {
              "field": "tags",
              "containsKey": "application"
            }
          },
          {
            "field": "type",
            "equals": "Microsoft.Storage/storageAccounts"
          }
        ]
    },
    "then": {
        "effect": "audit"
    }
}

Require tag

The following policy denies requests that don't have a tag containing "costCenter" key (any value can be applied):

{
  "if": {
    "not" : {
      "field" : "tags",
      "containsKey" : "costCenter"
    }
  },
  "then" : {
    "effect" : "deny"
  }
}

Trigger updates to existing resources

The following PowerShell script triggers an update to existing resources to enforce tag policies you have added.

$group = Get-AzureRmResourceGroup -Name "ExampleGroup" 

$resources = Find-AzureRmResource -ResourceGroupName $group.ResourceGroupName 

foreach($r in $resources)
{
    try{
        $r | Set-AzureRmResource -Tags ($a=if($_.Tags -eq $NULL) { @{}} else {$_.Tags}) -Force -UsePatchSemantics
    }
    catch{
        Write-Host  $r.ResourceId + "can't be updated"
    }
}

Next steps