Azure Policy pattern: parameters
A policy definition can be made dynamic to reduce the number of policy definitions that are needed by using parameters. The parameter is defined during policy assignment. Parameters have a set of pre-defined properties that describe the parameter and how it's used.
Sample 1: String parameters
This policy definition uses two parameters, tagName and tagValue, to set what the policy assignment is looking for on resources. This format allows the policy definition to be used for any number of tag name and tag value combinations, but only maintain a single policy definition.
Note
For a tag sample that uses mode All and works with a resource group, see Pattern: Tags - Sample #1.
{
"properties": {
"displayName": "Require tag and its value",
"policyType": "BuiltIn",
"mode": "Indexed",
"description": "Enforces a required tag and its value. Does not apply to resource groups.",
"parameters": {
"tagName": {
"type": "String",
"metadata": {
"description": "Name of the tag, such as costCenter"
}
},
"tagValue": {
"type": "String",
"metadata": {
"description": "Value of the tag, such as headquarter"
}
}
},
"policyRule": {
"if": {
"not": {
"field": "[concat('tags[', parameters('tagName'), ']')]",
"equals": "[parameters('tagValue')]"
}
},
"then": {
"effect": "deny"
}
}
}
}
Sample 1: Explanation
"tagName": {
"type": "String",
"metadata": {
"description": "Name of the tag, such as costCenter"
}
},
In this portion of the policy definition, the tagName parameter is defined as a string and a description is provided for its use.
The parameter is then used in the policyRule.if block to make the policy dynamic. Here, it's used to define the field that is evaluated, which is a tag with the value of tagName.
"if": {
"not": {
"field": "[concat('tags[', parameters('tagName'), ']')]",
"equals": "[parameters('tagValue')]"
}
},
Sample 2: Array parameters
This policy definition uses a single parameter, listOfBandwidthinMbps, to check if the Express Route Circuit resource has configured the bandwidth setting to one of the approved values. If it doesn't match, the creation or update to the resource is denied.
{
"properties": {
"displayName": "Allowed Express Route bandwidth",
"description": "This policy enables you to specify a set of express route bandwidths that your organization can deploy.",
"parameters": {
"listOfBandwidthinMbps": {
"type": "Array",
"metadata": {
"description": "The list of SKUs that can be specified for express route.",
"displayName": "Allowed Bandwidth"
}
}
},
"policyRule": {
"if": {
"allOf": [{
"field": "type",
"equals": "Microsoft.Network/expressRouteCircuits"
},
{
"not": {
"field": "Microsoft.Network/expressRouteCircuits/serviceProvider.bandwidthInMbps",
"in": "[parameters('listOfBandwidthinMbps')]"
}
}
]
},
"then": {
"effect": "Deny"
}
}
}
}
Sample 2: Explanation
"listOfBandwidthinMbps": {
"type": "Array",
"metadata": {
"description": "The list of SKUs that can be specified for express route.",
"displayName": "Allowed Bandwidth"
}
}
In this portion of the policy definition, the listOfBandwidthinMbps parameter is defined as an array and a description is provided for its use. As an array, it has multiple values to match.
The parameter is then used in the policyRule.if block. As an array parameter, an array condition's in or notIn must be used. Here, it's used against the serviceProvider.bandwidthInMbps alias as one of the defined values.
"not": {
"field": "Microsoft.Network/expressRouteCircuits/serviceProvider.bandwidthInMbps",
"in": "[parameters('listOfBandwidthinMbps')]"
}
Sample 3: Parameterized effect
A common way to make policy definitions reusable is to parameterize the effect itself. This example uses a single parameter, effect. Parameterizing the effect makes it possible to assign the same definition to different scopes with different effects.
{
"properties": {
"displayName": "All authorization rules except RootManageSharedAccessKey should be removed from Service Bus namespace",
"policyType": "BuiltIn",
"mode": "All",
"description": "Service Bus clients should not use a namespace level access policy that provides access to all queues and topics in a namespace. To align with the least privilege security model, you should create access policies at the entity level for queues and topics to provide access to only the specific entity",
"metadata": {
"version": "1.0.1",
"category": "Service Bus"
},
"parameters": {
"effect": {
"type": "string",
"defaultValue": "Audit",
"allowedValues": [
"Audit",
"Deny",
"Disabled"
],
"metadata": {
"displayName": "Effect",
"description": "The effect determines what happens when the policy rule is evaluated to match"
}
}
},
"policyRule": {
"if": {
"allOf": [{
"field": "type",
"equals": "Microsoft.ServiceBus/namespaces/authorizationRules"
},
{
"field": "name",
"notEquals": "RootManageSharedAccessKey"
}
]
},
"then": {
"effect": "[parameters('effect')]"
}
}
}
}
Sample 3: Explanation
"parameters": {
"effect": {
"type": "string",
"defaultValue": "Audit",
"allowedValues": [
"Audit",
"Deny",
"Disabled"
],
"metadata": {
"displayName": "Effect",
"description": "The effect determines what happens when the policy rule is evaluated to match"
}
}
},
In this portion of the policy definition, the effect parameter is defined as string. The policy definition sets the default value for an assignment to audit and limits the other options to disabled and deny.
The parameter is then used in the policyRule.then block for the effect.
"then": {
"effect": "[parameters('effect')]"
}
Next steps
- Review other patterns and built-in definitions.
- Review the Azure Policy definition structure.
- Review Understanding policy effects.