Develop Azure Policies
What are Azure Policies
Azure Policy is a service in Azure that you use to create, assign, and manage policies. These policies enforce different rules and effects over your resources, so those resources stay compliant with your corporate standards and service level agreements. Azure Policy meets this need by evaluating your resources for non-compliance with assigned policies.
When Azure resources are developed as self service products, the spn that deploys the resource has owner permissions on the resource.
A policy can be used to define rules for:
- Security practices
- Cost management
- Specific rules (like naming, locations, etc.)
What is the difference with RBAC
There are a few key differences between policies and role-based access control (RBAC). RBAC focuses on user actions at different scopes. You might be added to the contributor role for a resource group, allowing you to make changes to that resource group. A policy focuses on resource properties during deployment and for already existing resources. A policy controls properties such as the types or locations of resources. Unlike RBAC, a policy is a default allow and explicit deny system.
Guidelines
Azure policies are considered as Infrastructure as Code and therefor the same coding standards are followed.
More information can be found at Code Development Standards
Technical background of Azure Policy
Public documentation:
An Azure Policy definition is created in JSON format, according to this schema:
The policy definition contains elements for:
- displayName
- description
- mode
- parameters
- policy rule
- effect
Mode
The mode determines which resource types will be evaluated for a policy. The supported modes are:
- all: evaluate resource groups and all resource types
- indexed: only evaluate resource types that support tags and location
It is recommended to set the mode to ‘all’ in most cases. Only when auditing specific resource types or in testing scenario’s I would set the mode to ‘indexed’
Parameters
Parameters help simplify the policy management by reducing the number of policy definitions. For example, parameters such as ,the fields on a form – name, address, city, state. These parameters always stay the same, however their values change based on the individual filling out the form. Parameters work the same way when building policies. By including parameters in a policy definition, one can reuse that policy for different scenarios by using different values.
Policy Rules
The policy rule consists of If and Then blocks. In the If block, you define one or more conditions that specify when the policy is enforced. You can apply logical operators to these conditions to precisely define the scenario for a policy.
In the Then block, you define the effect that happens when the If conditions are fulfilled.
Logical operators
Supported logical operators are:
- “not”: {condition or operator}
- “allOf”: [{condition or operator},{condition or operator}]
- “anyOf”: [{condition or operator},{condition or operator}]
- The not syntax inverts the result of the condition. The allOf syntax (similar to the logical And operation) requires all conditions to be true. The anyOf syntax (similar to the logical Or operation) requires one or more conditions to be true.
Conditions
A condition evaluates whether a field meets certain criteria. The supported conditions are:
- “equals”: “value”
- “notEquals”: “value”
- “like”: “value”
- “notLike”: “value”
- “match”: “value”
- “notMatch”: “value”
- “contains”: “value”
- “notContains”: “value”
- “in”: [“value1″,”value2”]
- “notIn”: [“value1″,”value2”]
- “containsKey”: “keyName”
- “notContainsKey”: “keyName”
- “exists”: “bool”
Effect
The effect is the possible response of the policy definition to a non-compliant resource.
In the example, Deny is the wanted effect as it is not wanted to create non-compliant resources in the Azure environment. Audit is a good first choice for a policy effect to determine what the impact of a policy is before setting it to Deny.
There are currently six effects that are supported in a policy definition:
- Append
- Audit
- AuditIfNotExists
- Deny
- DeployIfNotExists
- Disabled
Creating a Policy definition
Before creating a policy definition, first determine what can be audited with a policy.
The first step is to understand the available properties of the resource that must be audited. These properties can be found in the Azure Resource Manager Templates reference documentation Resource Manager Templates
In the below example the storage account resource will be used as an example.
The property that will be audited is: using only HTTPS. The reference documentation shows that supportsHttpsTrafficOnly is the property to validate.
Now that it is determined what properties need to be audited, it must be investigated what the alias for this property is. This is needed in a later step in the policy definition.
The alias can be found using PowerShell with the command:
(Search-AzGraph -Query "where type=~'microsoft.storage/storageaccounts' | limit 1").aliases | ConvertTo-Json
The next snippet is part of the result of the previous query and contains the part that is needed for the policy definition.
{ "Microsoft.Storage/storageAccounts/supportsHttpsTrafficOnly": false, }
Composing the policy
Now all required information, to create a policy, is gathered, it can all be put together to actually compose the policy.
A policy is basically a JSON file that follows a specific pattern. In the following example the policy is broken apart in three sections.
Putting it all together will result in a policy definition file.
Policy metadata
First fill in the metadata containing the displayName and description of the policy.
Policy Rule
The second step is to add the policy rule which tells the policy how to respond on the findings.
In this case evaluate the resource type ‘storage account’ and the property ‘supportsHttpsTrafficOnly’. Add these to the policy rule.
Policy effect
The last part that needs to be added is the policy effect, which can be one of the six previously mentioned options.
In this case traffic must be denied if it doesn’t use HTTPS.
With all parts of the policy put together the end result will look something like:
Saving the policy file
When writing alot of policies it helps to give the policy definitions a sensable name that describes what de policy does.
In the previous example a good name would be StoragePolicyDefinition.json
If there are parameters used in the policy definition it is best practise to store the parameter values in a separate JSON file. For all my code i’m trying to use the same naming principal so in this case I would store the parameters in a file called StoragePolicyDefinition.parameters.json
Sample Code
An example policy definition can be found on my gitHub by following this link