What is Azure Policy?

Azure policies ensures proper cloud governance by controlling resource deployment, usage and enforcing standards in your Azure Environment. Played around with Azure Policies during a trip to the cabin. Thought I should make a post about it.

Azure Policy is a service you can use to create, assign and manage policy. These policies enforces rules resources must follow. For instance, a policy can enforce rules during during creation of a resource, like the resource must include a certain tag. Policies can also be applied to existing resources, such as all resources must be located in a certain region to give visibility into compliance.

Another useful policy is that you can enforce naming convention to keep a consistent naming standard. Azure comes with some default policies, these are as follows:

Require SQL Server 12.0 – Ensures SQL servers are version

Allowed Storage Account SKUs – Controls Storage Account SKU size

Allowed Resource Types – Controls which types of resources can be deployed

Allowed Locations – Controls which locations that resources can be deployed into

Allowed Virtual Machine SKUs – Limits virtual machine SKUs that can be deployed

Apply tag and its default values – If the specified tag is not provided by the user, apply a default value

Enforce tag and its value – Resource deployment succeeds only if a specific tag and value are supplied

Not allowed resource types – Lists resources that cannot be deployed

How to work with custom policies

If we want to create custom policy can use JSON (JavaScript Object Notation) format for granular resource control. Because the built-in policies doesn’t always support our requirements. For instance, if you want to limit creation of certain resources to IT admins or other users.

There are different ways you can create custom policies:

  • Manually, by understanding and customize the JSON format
  • Copy an existing policy, tweak and customize to current needs
  • Use policies made by others posted on GitHub.

Policy parameter

Policies supports the notion of parameters, like parameters in PowerShell or bash scripts in Linux. These variables are passed to the policy, and are unique to the current use for each policy, this simplifies the policy management by reducing the number of policy definitions we create, by making the policies more generic. It allows us to reuse policy definition for different scenarios, such as specifying one set of locations or subscriptions.

Policy Assignment

A policy assignment is a policy definition assigned to a scope. A scope can range from management group to a resource group. The term scope is referred to as all resource groups, subscription and management groups, and policies assign to a selected scope are then inherited by all child resources.

To put a policy into use an assignment to scope must be assigned. If there are resources within the scope that needs to be excluded from the policy, you can specify exceptions from the policy, such as a virtual machine or storage account.

Policy assignment applies to both built-in and custom policies, and we can assign them using Azure Portal, PowerShell Cmdlet, Azure CLI. For this we need the permission of Microsoft.Authorization/policyassignments/writes. More on creating and assigning policies with PowerShell later in this post.

Policy effects

All policy definition in Azure Policy has a single effect. The effect determines what happens when the policy is evaluated to match, and behaves differently if the policies are new for a resource, an updated resource or an existing resource.

The effects below are currently supported in a policy definition, and are declared in the JSON definition format. In this post I haven’t gone in complete detail of how the JSON format is structured and formed, only a short description of the effects of the policies.

Append

This effect is useful when you need to add additional fields to the requested resource during creation and update. An example of that is adding tags on resources, such as Customer that can be used to filter cost by customers in Cost Center.

Audit

The audit effect is used to create warning events in the activity log when evaluating a non-compliant resource, but doesn’t stop the request.

AuditIfNotExists

This enables auditing on resources that match the if condition, that doesn’t have the components specified in the details of the then condition. In short, auditing is enabled if resource does not exist.

Deny

Used to prevent resource request that doesn’t match the policy. Raises an error and fails the request.

DeployIfNotExists

Similar to the AuditIfNotExists. DeployIfNotExists executes a template deployment when the condition is met, instead of auditing the effect that does’t exists.

An example can be, it evaluates SQL Server Databases to determines if encryption is enables. If not, then an deployment to enable is executed. In other words; if the resource doesn’t already exist, deploy it.

Disabled

This effect is useful in testing situations or when the policy definition has parameterized the effect. This flexibility makes it possible to disable single assignments instead of disabling all of that policy’s assignments.

Policy Initiative Definitions

Policy initiative definition is a collection of policies that is custom-made to achieve a singular overall goal. It allows us to group multiple Azure policies into a single unit, useful for security reasons for instance when a single Azure governance goal consists of multiple checks. For instance:

  • Monitor unencrypted SQL Databases in Security Center
  • Monitor OS vulnerabilities in Security Center
  • Monitor missing Endpoint Protection in Security Center.

By creating an initiative definition like Enable Monitoring in Security Center, we can assigned this initiative in the same way as a single policy. In this way we work with the initiative policy, instead of getting into detail of each individual policies.

Adding Policies with PowerShell

How can you assign policies with Azure PowerShell, played around with PowerShell and policy assignment and ended with the following script. This assigns an already existing policy to a specified scope.

The first thing I did was to create the functionality in the process block and then later created an advanced function out of it. Now, what does the code do? The code in the process block retrieves the resource group specified from the parameter and stores it in a variable, and then retrieves the specified policy from the parameter, then assigning the policy to the resource group.

function New-AzAssignPolicy {
    [CmdletBinding()]
    param (
        # Name of the resource group
        [Parameter(Mandatory = $true)]
        [String]
        $ResourceGroup,
        # Name of the new poliy assignment
        [Parameter(Mandatory = $true)]
        [String]
        $PolicyName,
        # Name of the policy to be assigned
        [Parameter(Mandatory = $true)]
        [String]
        $PolicyDisplayName

    )
    process {
        Write-Verbose "Retrieving information about the specified resource group..."
        $RGroup = Get-AzResourceGroup -Name $ResourceGroup

        Write-Verbose "Retrieving information about the specified policy..."
        $PolicyDefinition = Get-AzPolicyDefinition | `
            Where-Object { $_.Properties.DisplayName -eq $PolicyName }

        Write-Verbose "Assigning $PolicyName policy to specified resource group $ResourceGroup..."
        New-AzPolicyAssignment -Name $PolicyDisplayName `
            -DisplayName $PolicyDisplayName `
            -Scope $RGroup.ResourceId `
            -PolicyDefinition $PolicyDefinition

        Write-Verbose "Assigning complete..."
    }
}

To load the script in to memory, to use it. Use dot source like so . .New-AzAssignPolicy.ps1 if your in the current directory in a command window or load everything with F5 in PowerShell ISE or mark everything and hit F8, this works in both VS Code and PS ISE.

Then you can run the command like below, and you should see in the Azure Portal under Polices that a new policy has been assigned. How cool right?

NOTE: Remember to login into your Azure Portal from the command line and install the Az module in PowerShell for the commands to work.

    New-AzAssignPolicy -ResourceGroup "rg1" -PolicyName "Enforce tag on resource" -PolicyDisplayName

Keep in mind that resources are scanned hourly for compliance with the policies configuration, so if you make changes to a policy the affect may not be immediately. Changes can take from a minute to up to an hour, so be patient.

Hope you enjoyed! Going for a walk now.