Azure Resource Manager Policy to add cost center and owner tags

Azure Resource Manager (ARM) allows you to enforce organisational standards through the use of custom policies.  There are a number of things that you can do with ARM policies.  These range from restricting the size of virtual machines and the location they can be deployed, through to ensuring standardised naming conventions.

ARM Policies are made up of conditions, logical operators and effects.  Policies can be applied to a subscription, resource group or resource.

{
  "if" : {
      <condition> | <logical operator>
  },
  "then" : {
      "effect" : "deny | audit | append"
  }
}

As it currently stands, if an ARM Policy is applied which requires specific ARM tags to present, deployment of resources via the Azure Portal is blocked by the ARM Policy.  The resource deployment blades in portal.azure.com do not allow the setting of tags as part of the deployment as such the ARM Policy stops the deployment.  For some customers this is not a problem as all resources are deployed using ARM templates and any template which does not have the right tags set will not be allowed to deploy. But for many customers ‘breaking’ the UI experience is really bad.

As ARM Policies have an effect of append as well as deny, a set of policies can be created to append default tags to resources as they are created, these can then be updated via the UI (or PowerShell or CLI).  This allows staff to continue using the UI for resource deployment but they will have to update the tags once the resource is provisioned.

To force all resources created in a resource group to have a default tag of ‘owner’ and ‘costcenter’ added (if not present) when the resource is being created, the following ARM Policies need to be created.

CostCenterTag.JSON

This Policy fires if tags are present for the resource but the costcenter tag is not present.  The policy appends the costcenter tag with a default value.

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

OwnerTag.JSON

This Policy fires if tags are present for the resource but the owner tag is not present.  The policy appends the owner tag with a default value.

{
  "if": {
    "allof": [
      {
        "field": "tags",
        "exists": "true"
      },
      {
        "field": "tags.owner",
        "exists": "false"
      }
    ]
  },
  "then": {
    "effect": "append",
    "details": [
      {
        "field": "tags.owner",
        "value": "Daniel"
      }
    ]
  }
}
NoTagsPresent.JSON
This policy fires if the resource has no tags and adds the costcenter and owner tags with default values.
{
  "if": {
    "field": "tags",
    "exists": "false"
  },
  "then": {
    "effect": "append",
    "details": [
{
        "field": "tags",
        "value": {"costCenter":"666", "owner":"daniel"   }

      },
      
        ]
  }
}

All three policies need to be applied so that tags are added under the scenario that an ARM template is used that contains other tags and the scenario that a deployment is done via the UI or using an ARM template and no tags are specified .

These Policies and the PowerShell commands to deploy the policies can be downloaded from https://github.com/dbowbyes/ARM

A copy of the PowerShell script used to deploy the ARM Policies is included below.

$mysubscription = 
$myresourcegroup =


login-azurermaccount
Get-AzureRmSubscription
Select-AzureRmSubscription -SubscriptionId $mysubscription

$policy = New-AzureRmPolicyDefinition -Name tags-owner -Description "Policy to set owner tags" -Policy "tags-owner.json"
New-AzureRmPolicyAssignment -Name tags-owner -PolicyDefinition $policy -Scope /subscriptions/$mysubscription/resourceGroups/$myresourcegroup

$policy = New-AzureRmPolicyDefinition -Name tags-costcenter -Description "Policy to set costcenter" -Policy "tags-costcenter.json"
New-AzureRmPolicyAssignment -Name tags-costcenter -PolicyDefinition $policy -Scope /subscriptions/$mysubscription/resourceGroups/$myresourcegroup

$policy = New-AzureRmPolicyDefinition -Name tags-notags -Description "Policy to set costcenter" -Policy "tags-notags.json"
New-AzureRmPolicyAssignment -Name tags-notags -PolicyDefinition $policy -Scope /subscriptions/$mysubscription/resourceGroups/$myresourcegroup

The following command can be used to see what ARM Policies have been applied to a subscription or resource group

get-azureRMpolicyassignment -Scope /subscriptions/$mysubscription/resourceGroups/$myresourcegroup

More information and examples of ARM Policies can be found here.

Advertisements

2 responses to “Azure Resource Manager Policy to add cost center and owner tags

  1. Pingback: Using ARMclient to directly access Azure ARM REST API’s and list ARM Policy details | Daniel's Blog

  2. You might also consider to add a policy that verifies that these tags have the correct value in case they are set during creation. something like:
    {
    “if” : {
    “allOf”: [
    { “field”: “tags”, “exists”: “true” },
    { “field”: “tags.costCenter”,”exists”: “true”},
    { “not”: {“field”: “tags.costCenter”,”equals”: “666” }}
    ]
    },
    “then”: {
    “effect”: “deny”
    }
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s