Stage 4 · Provision
Bicep & ARM Templates for Azure
Azure Policy & Blueprints
Governance at scale, initiative definitions, and remediation tasks — enforcing standards across Azure subscriptions.
What Is Azure Policy?
Azure Policy is a service that evaluates Azure resources against organizational standards. It can audit non-compliant resources, deny deployments that violate policies, and automatically remediate existing resources. Policies run at the subscription or management group level.
Azure Policy is built into the Azure platform — it runs automatically on every resource creation and modification. Unlike post-deployment validation, policy enforcement happens at the API level before resources are provisioned.
Policy Definitions
A policy definition is a JSON file that defines the rule to evaluate. Azure provides hundreds of built-in policies. You can create custom policies using Azure Policy's built-in effect types: Audit, Deny, DeployIfNotExists, and Modify.
{
"name": "require-cost-center-tag",
"displayName": "Require CostCenter tag",
"description": "Ensures all resources have a CostCenter tag",
"mode": "Indexed",
"parameters": {},
"policyRule": {
"if": {
"not": {
"field": "[concat('tags[', 'CostCenter', ']')]",
"exists": "true"
}
},
"then": {
"effect": "deny"
}
}
}The policyRule has an if condition and a then effect. The if block checks whether the CostCenter tag exists. If it does not, the deny effect blocks the deployment. The mode Indexed means the policy only evaluates resource types that support tags.
param policyDefinitionName string = 'require-cost-center-tag'
param location string = resourceGroup().location
resource policyDef 'Microsoft.Authorization/policyDefinitions@2023-04-01' = {
name: policyDefinitionName
properties: {
policyType: 'Custom'
mode: 'Indexed'
displayName: 'Require CostCenter tag'
policyRule: {
if: {
not: {
field: 'tags[CostCenter]'
exists: true
}
}
then: {
effect: 'deny'
}
}
}
}
resource policyAssignment 'Microsoft.Authorization/policyAssignments@2023-04-01' = {
name: 'require-cost-center'
location: location
properties: {
policyDefinitionId: policyDef.id
scope: subscription().id
}
}Bicep can deploy policy definitions and assignments. The policyDefinition resource creates the policy. The policyAssignment resource applies it to a scope — subscription, resource group, or management group.
Policy Initiatives
An initiative groups multiple related policies into a single deployable unit. Instead of assigning policies individually, you assign an initiative that bundles them. This simplifies governance at scale.
{
"name": "security-baseline",
"displayName": "Security Baseline Initiative",
"description": "Common security policies for all subscriptions",
"policyType": "Custom",
"parameters": {},
"policyDefinitions": [
{
"policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/404c9b61-e669-4ab0-b786-6b6030637405",
"policyDefinitionReferenceId": "requireEncryption"
},
{
"policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/1f314764-cb73-4fc9-b863-8eca98ac36e9",
"policyDefinitionReferenceId": "restrictRegions"
}
]
}The initiative references built-in policies by their IDs. Each policy gets a reference ID for tracking compliance. Initiatives can include both built-in and custom policies.
Policy Assignments
Assignments apply policies or initiatives to a scope — a management group, subscription, or resource group. Assignments inherit from parent scopes. A policy assigned at the management group level applies to all subscriptions in that group.
$ az policy assignment create \
--name "require-cost-center" \
--display-name "Require CostCenter tag" \
--policy "require-cost-center-tag" \
--scope "/subscriptions/{subscription-id}"
# Assign at management group scope
$ az policy assignment create \
--name "security-baseline" \
--policy-set-definition "security-baseline" \
--scope "/providers/Microsoft.Management/managementGroups/{mg-id}"The scope parameter determines where the policy applies. Policies at the management group level cascade to all child subscriptions. Use --enforcement-mode to control whether the policy blocks or only audits.
Remediation Tasks
When a policy uses DeployIfNotExists or Modify effects, existing non-compliant resources can be remediated. A remediation task scans existing resources and applies the policy's deploy or modify logic to bring them into compliance.
$ az policy remediation create \
--name "remediate-cost-center" \
--policy-assignment "require-cost-center" \
--scope "/subscriptions/{subscription-id}"
# Check remediation status
$ az policy remediation list --scope "/subscriptions/{subscription-id}"
$ az policy remediation show --name "remediate-cost-center" --scope "/subscriptions/{subscription-id}"The remediation task scans all existing resources in scope and applies the policy's logic. For DeployIfNotExists policies, it creates the missing resource. For Modify policies, it applies the specified modifications.
Azure Blueprints
Azure Blueprints orchestrate the deployment of policy assignments, role assignments, ARM templates, and resource groups. They provide a repeatable way to set up new subscriptions with the correct governance configuration.
{
"kind": "policyAssignment",
"name": "require-tags",
"properties": {
"displayName": "Require tags on all resources",
"policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/require-cost-center-tag",
"enforcementMode": "Default"
}
}Blueprint artifacts define what gets deployed to a subscription. Policy assignments, role assignments, and ARM templates can all be included. Blueprints are versioned and can be assigned to multiple subscriptions.
Microsoft is transitioning from Blueprints to deployment stacks. Blueprints remain supported but new features go to deployment stacks. For new projects, evaluate deployment stacks as an alternative.
Deny blocks deployments. Audit logs warnings. DeployIfNotExists and Modify can create or change resources automatically. Test each effect in a non-production subscription before deploying to production.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.