DEV Community

Cover image for Using Bicep to create an Azure Policy definition
Massimo Bonanni
Massimo Bonanni

Posted on • Updated on

Using Bicep to create an Azure Policy definition

In this post I would like to show you how you can create an Azure Policy definition in your subscription using a Bicep template.

First of all, what is an Azure Policy?
Looking at the documentation (here), we find this definition:

Azure Policy helps to enforce organizational standards and to assess compliance at-scale

Using Azure Policies, you can implement governance on your resources forcing some characteristics or properties on your resources.

An Azure Policy is, basically, a JSON file like the following:

{
    "properties": {
        "displayName": "Allow skus for App Service",
        "policyType": "Custom",
        "description": "This policy allows to define the permitted skus for the App Service instance",
        "mode": "Indexed",
        "metadata": {
            "category": "Web App"
        },
        "parameters": {
            "allowedSkus": {
                "type": "array",
                "metadata": {
                    "description": "The list of skus can be used for the App Service plan (e.g. Free or PremiumV3)",
                    "displayName": "Allowed skus"
                }
            }
        },
        "policyRule": {
            "if": {
                "allOf": [
                    {
                        "field": "type",
                        "equals": "Microsoft.Web/serverfarms"
                    },
                    {
                        "not": {
                            "field": "Microsoft.Web/serverfarms/sku.tier",
                            "in": "[parameters('allowedSkus')]"
                        }
                    }
                ]
            },
            "then": {
                "effect": "deny"
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

This policy sample allow us check that all the App Service Plan resources we create will have one of the sku we set in the input parameters.

As you can see in the previous JSON, you have different sections in the policy definition.

Policy Metadata

In this part of the policy definition, you can set the metadata for the policy, e.g. the name, the description and so on:

"displayName": "Allow skus for App Service",
"policyType": "Custom",
"description": "This policy allows to define the permitted skus for the App Service instance",
"mode": "Indexed",
"metadata": {
    "category": "Web App"
},
Enter fullscreen mode Exit fullscreen mode

Using these properties, you can set the display name, the description and the type of the policy. All these values will appear in the Azure portal when you or someone will use the policy.

Policy parameters

This part of the definition allows you to pass values when you will assign the policy. You can assign the same definition with different parameters to different scope.

"parameters": {
    "allowedSkus": {
        "type": "array",
        "metadata": {
            "description": "The list of skus can be used for the App Service plan (e.g. Free or PremiumV3)",
            "displayName": "Allowed skus"
        }
    }
},
Enter fullscreen mode Exit fullscreen mode

In our sample, we declare a parameter called allowedSkus, its type is an array (you will pass value with the syntax ["Premium","Free"]), and we define the appearance of the parameter in the portal (the metadata section).

Policy rule

Basically, a Policy is an IF: is some condition is true, then you apply an effect.
In the policyRule part of the policy JSON, you can define the condition and the effect:

"policyRule": {
    "if": {
        "allOf": [
            {
                "field": "type",
                "equals": "Microsoft.Web/serverfarms"
            },
            {
                "not": {
                    "field": "Microsoft.Web/serverfarms/sku.tier",
                    "in": "[parameters('allowedSkus')]"
                 }
            }
        ]
    },
    "then": {
        "effect": "deny"
    }
}
Enter fullscreen mode Exit fullscreen mode

In our sample, if the type of the resource we are managing is Microsoft.Web/serverfarms (it is an App Service Plan) and the value of the tier property of the sku object is not in the value we passed in the parameter, then the effect is deny.
Deny means that you canno create that resource, even if you are all the permissions!
More info about the affects you can use in a policy are available to this link.

Creating the template

Once you have the policy definition (the JSON), is easy to create a Bicep template that allows you to create the definition in your subscription.

targetScope = 'subscription'

var policyDefinitionName = 'AllowSkusAppService'

resource policyDefinition 'Microsoft.Authorization/policyDefinitions@2020-03-01' = {
  name: policyDefinitionName
  properties: {
    // Here you add the "bicepted" policy JSON 
  }
}
Enter fullscreen mode Exit fullscreen mode

In the previous Bicep template, you can find the term "bicepted" that means you take the JSON of the policy and

  • remove the char " before and after the property names,
  • substitute the char " with the ' in the values,
  • remove the , at the end of the lines,
  • use the \' instead ' when you want to use ' as part of the value,

and you have:

targetScope = 'subscription'

var policyDefinitionName = 'AllowSkusAppService'

resource policyDefinition 'Microsoft.Authorization/policyDefinitions@2020-03-01' = {
  name: policyDefinitionName
  properties: {
    policyType: 'Custom' 
    mode: 'Indexed'
    description: 'This policy allows to define the permitted skus for the App Service instance'
    displayName: 'Allow skus for App Service'
    metadata: {
      category : 'WebApp'
    }
    parameters: {
      allowedSkus: {
        type: 'array'
        metadata: {
          description: 'The list of skus can be used for the App Service plan (e.g. Free or PremiumV3)'
          displayName: 'Allowed skus'
        }
      }
    }
    policyRule: {
      if: {
        allOf: [
            {
                field: 'type'
                equals: 'Microsoft.Web/serverfarms'
            }
            {
                not: {
                    field: 'Microsoft.Web/serverfarms/sku.tier'
                    in: '[parameters(\'allowedSkus\')]'
                }
            }
        ]
    }
      then: {
        effect: 'deny'
      }
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

To deploy the template and create the policy definition you can use the command:

az deployment sub create --location <your region> --template-file <templatename>.bicep
Enter fullscreen mode Exit fullscreen mode

Top comments (0)