
Azure Policy
In the previous section, we talked about applying tags for Azure deployments. Tags are great for organizing resources; however, there is one more thing that was not discussed: how do organizations ensure that tags are applied for every deployment? There should be automated enforcement of Azure tags to resources and resource groups. There is no check from Azure to ensure that appropriate tags are applied to resources and resource groups. This is not just specific to tags—this applies to the configuration of any resource on Azure. For example, you may wish to restrict where your resources can be provisioned geographically (to only the US-East region, for instance).
You might have guessed by now that this section is all about formulating a governance model on Azure. Governance is an important element in Azure because it ensures that everyone accessing the Azure environment is aware of organizational priorities and processes. It also helps to bring costs under control. It helps in defining organizational conventions for managing resources.
Each policy can be built using multiple rules, and multiple policies can be applied to a subscription or resource group. Based on whether the rules are satisfied, policies can execute various actions. An action could be to deny an ongoing transaction, to audit a transaction (which means writing to logs and allowing it to finish), or to append metadata to a transaction if it's found to be missing.
Policies could be related to the naming convention of resources, the tagging of resources, the types of resources that can be provisioned, the location of resources, or any combination of those.
Azure provides numerous built-in policies and it is possible to create custom policies. There is a policy language based on JSON that can be used to define custom policies.
Now that you know the purpose and use case of Azure Policy, let's go ahead and discuss built-in policies, policy language, and custom policies.
Built-in policies
Azure provides a service for the creation of custom policies; however, it also provides some out-of-the-box policies that can be used for governance. These policies relate to allowed locations, allowed resource types, and tags. More information for these built-in policies can be found at https://docs.microsoft.com/azure/azure-resource-manager/resource-manager-policy.
Policy language
Policies in Azure use JSON to define and describe policies. There are two steps in policy adoption. The policy should be defined and then it should be applied and assigned. Policies have scope and can be applied at the management group, subscription, or resource group level.
Policies are defined using if...then blocks, similar to any popular programming language. The if block is executed to evaluate the conditions, and based on the result of those conditions, the then block is executed:
{
"if": {
<condition> | <logical operator>
},
"then": {
"effect": "deny | audit | append"
}
}
The policies not only allow simple if conditions but also allow multiple if conditions to be joined together logically to create complex rules. These conditions can be joined using AND, OR, and NOT operators:
The AND syntax requires all conditions to be true.
The OR syntax requires one of the conditions to be true.
The NOT syntax inverts the result of the condition.
The AND syntax is shown next. It is represented by the allOf keyword:
"if": {
"allOf": [
{
"field": "tags",
"containsKey": "application"
},
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
}
]
},
The OR syntax is shown next. It is represented by the anyOf keyword:
"if": {
"anyOf": [
{
"field": "tags",
"containsKey": "application"
},
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
}
]
},
The NOT syntax is shown next. It is represented by the not keyword:
"if": {
"not": [
{
"field": "tags",
"containsKey": "application"
},
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
}
]
},
In fact, these logical operators can be combined together, as follows:
"if": {
"allOf": [
{
"not": {
"field": "tags",
"containsKey": "application"
}
},
{
"field": "type",
"equals": "Microsoft.Storage/storageAccounts"
}
]
},
This is very similar to the use of if conditions in popular programming languages such as C# and Node.js:
If ("type" == "Microsoft.Storage/storageAccounts") {
Deny
}
It is important to note that there is no allow action, although there is a Deny action. This means that policy rules should be written with the possibility of denial in mind. Rules should evaluate conditions and Deny the action if the conditions are met.
Allowed fields
The fields that are allowed in conditions while defining policies are as follows:
Name: The name of the resource for applying the policy to. This is very specific and applicable to a resource by its usage.
Type: The type of resource, such as Microsoft.Compute/VirtualMachines. That would apply the policy to all instances of virtual machines, for example.
Location: The location (that is, the Azure region) of a resource.
Tags: The tags associated with a resource.
Property aliases: Resource-specific properties. These properties are different for different resources.
In the next section, you will learn more about safekeeping resources in production environments.