Today I want to show a really useful Azure feature to help you with the governance of your Azure Subscriptions: Azure Resource Policies:

Resource policies enable you to establish conventions for resources in your organization. By defining conventions, you can control costs and more easily manage your resources. For example, you can specify that only certain types of virtual machines are allowed, or you can require that all resources have a particular tag. Policies are inherited by all child resources. So, if a policy is applied to a resource group, it is applicable to all the resources in that resource group.

How Resource Policies works

First of all, you need a policy definition. Here a description of the structure.

Let’s create one!

You can create policies definitions directly with the Azure Rest API or using PowerShell, the Azure CLI 1.0 or 2.0.

I prefer using PowerShell:

First login in Azure with: Login-AzureRmAccount and if you have more subscriptions, select the right one with Select-AzureRmSubscription.

Now let’s define the policy definition, this can be accomplished directly inline when calling the New-AzureRmPolicyDefinition cmdlet:

$policy = New-AzureRmPolicyDefinition -Name costCenterTagPolicyDefinition -Description "Policy to deny resource creation if no costCenter tag is provided" -Policy '{
  "if": {
    "not" : {
      "field" : "tags",
      "containsKey" : "costCenter"
    }
  },
  "then" : {
    "effect" : "deny"
  }
}'

or first creating a separate json file:

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

and then calling the New-AzureRmPolicyDefinition cmdlet with the json file as parameter:

$policy = New-AzureRmPolicyDefinition -Name costCenterTagPolicyDefinition -Description "Policy to deny resource creation if no costCenter tag is provided" -Policy "c:policiescostCenterTagPolicy.json"

The policy definition above throws an error if the tag “costCenter” is NOT provided.

Once you have a policy definition you can assign it to a Resource, Resource Groups or at Subscription level.

Let’s create a new Resource Group:

New-AzureRmResourceGroup -Name PolicyRG -Location "West Europe"

And now apply the policy definition to this Resource Group:

New-AzureRmPolicyAssignment -Name costCenterTagPolicyAssignment -PolicyDefinition $policy -Scope /subscriptions/ff1a0889-5f9e-44bc-908c-59e3e99361c3/resourceGroups/PolicyRG

Now I will deploy a storage account using an ARM template from the Azure quickstart template Github repo, which does not have the required tag costCenter:

New-AzureRmResourceGroupDeployment -Name ExampleDeployment -ResourceGroupName PolicyRG -TemplateFile D:Sourcesazure-quickstart-templates101-storage-account-createazuredeploy.json -TemplateParameterFile D:Sourcesazure-quickstart-templates101-storage-account-createazuredeploy.parameters.json

and we see the error:

The error will be logged also in the Activity log in the Portal:

Now let’s modify the storage account template and add the required tag:

And retry the deployment:

Yes! This works now!

In this example we were applying a Deny effect, but there are more:

  • Deny generates an event in the audit log and fails the request.
  • Audit generates a warning event in audit log but does not fail the request.
  • Append adds the defined set of fields to the request.

More complex scenarios

You can create more complex policies definitions, like enforcing naming conventions, creation of resources only in some Regions, creation of only specific resource types etc…
Here some examples.

Conclusion

Azure Resource Policies are an underexposed feature which will help your organization with governance on the Azure Subscriptions, making the creation of resources more consistent across the DevOps teams.