Azure

Azure Policy

Azure Policy - governance, compliance, and resource management.

https://learn.microsoft.com/en-us/azure/governance/policy/

What is Azure Policy?

Azure Policy is a governance service that enables you to create, assign, and manage policies that control or audit your Azure resources. It acts as a guardrail system that ensures your cloud environment stays compliant with organizational standards, regulatory requirements, and best practices.

When you use Azure Policy, the system:

  1. Evaluates resources against defined rules and conditions
  2. Identifies resources that are non-compliant
  3. Prevents creation of non-compliant resources (enforcement mode)
  4. Automatically remediates non-compliant configurations (when configured)
  5. Provides compliance reports and insights

Azure Policy ensures governance at scale by enforcing rules across your entire Azure environment, from individual resources to organization-wide deployments.


Why Use Azure Policy?

1. Ensure Compliance

Maintain adherence to corporate standards, industry regulations (HIPAA, PCI-DSS, SOC 2), and security requirements without manual oversight.

2. Prevent Configuration Drift

Stop resources from being deployed or modified in ways that violate organizational policies, catching issues before they become problems.

3. Cost Control

Enforce policies that prevent expensive resource types, oversized VMs, or deployments in high-cost regions, directly impacting your cloud spending.

4. Security Enforcement

Automatically ensure security best practices like encryption, network restrictions, and proper authentication across all resources.

5. Audit and Visibility

Track which resources comply with policies and which don't, providing evidence for audits and compliance reviews.

6. Automated Remediation

Automatically fix non-compliant resources without manual intervention, reducing operational overhead and human error.


How Azure Policy Works

Basic Concept

Azure Policy evaluates resources based on rules you define, then takes action based on the policy effect:

Policy Evaluation Flow:

Resource Creation/Modification Request
    ↓
Azure Policy Evaluation
    ↓
├─ Compliant → Allow operation
└─ Non-Compliant → Apply Effect
    ├─ Deny: Block the operation
    ├─ Audit: Log but allow
    ├─ DeployIfNotExists: Remediate automatically
    ├─ Modify: Change configuration
    └─ Disabled: No action

Example - VM Size Restriction:

Policy Rule:
"Only allow Standard_D2s_v3 or smaller VMs in production"

User attempts to create Standard_D16s_v3 VM
    ↓
Azure Policy evaluates
    ↓
VM size violates policy
    ↓
Effect: Deny
    ↓
VM creation blocked with error message

Important: Policies are evaluated in real-time during resource operations and periodically (every 24 hours) for existing resources.


Core Concepts

Policy Definitions

A policy definition is a JSON document that describes the conditions to evaluate and the action to take.

Structure:

{
  "properties": {
    "displayName": "Allowed virtual machine size SKUs",
    "description": "This policy restricts VM sizes to approved SKUs",
    "mode": "Indexed",
    "policyRule": {
      "if": {
        "allOf": [
          {
            "field": "type",
            "equals": "Microsoft.Compute/virtualMachines"
          },
          {
            "not": {
              "field": "Microsoft.Compute/virtualMachines/sku.name",
              "in": [
                "Standard_B2s",
                "Standard_D2s_v3",
                "Standard_D4s_v3"
              ]
            }
          }
        ]
      },
      "then": {
        "effect": "deny"
      }
    }
  }
}

Policy Effects

Azure Policy supports multiple effects that determine what happens when a policy rule matches:

1. Deny

  • Blocks the resource operation
  • Returns an error to the user
  • Best for preventing non-compliant resources

Example: Prevent VMs without encryption

2. Audit

  • Creates a warning event in the activity log
  • Allows the operation to proceed
  • Best for tracking non-compliance without blocking

Example: Log when storage accounts don't use HTTPS

3. AuditIfNotExists

  • Checks if a related resource exists
  • Logs if the related resource is missing
  • Doesn't block operations

Example: Audit VMs without backup enabled

4. DeployIfNotExists

  • Automatically deploys a resource if it doesn't exist
  • Fixes non-compliance automatically
  • Best for ensuring required configurations

Example: Automatically enable diagnostic settings

5. Modify

  • Changes properties of a resource during creation or update
  • Adds, updates, or removes tags or other properties

Example: Automatically add cost center tags

6. Disabled

  • Policy is not evaluated
  • Useful for testing or temporary deactivation

Policy Scope and Inheritance

Azure Policy can be assigned at multiple levels, with inheritance flowing downward:

Management Group (Organization-wide)
    ├─ Subscription 1
    │   ├─ Resource Group A
    │   │   ├─ Resource 1
    │   │   └─ Resource 2
    │   └─ Resource Group B
    │       └─ Resource 3
    └─ Subscription 2
        └─ Resource Group C
            └─ Resource 4

Inheritance Rules:

  • Policies assigned at Management Group apply to all subscriptions beneath it
  • Policies assigned at Subscription apply to all resource groups
  • Policies assigned at Resource Group apply to all resources within
  • Child scopes inherit all parent policies automatically
  • Cannot override or remove inherited policies (only exclude specific resources)

Example:

Management Group: "Require tags on all resources"
    ↓ (inherited)
Subscription: "Allowed regions: East US, West US"
    ↓ (inherited)
Resource Group: "Require encryption on storage accounts"
    ↓ (all three policies apply)
Resources: Must comply with all three policies

Built-in Policies

Azure provides hundreds of built-in policy definitions across all service categories.

Common Built-in Policies by Category

Compute:

  • Allowed virtual machine size SKUs
  • Virtual machines should be migrated to new Azure Resource Manager resources
  • Managed disks should use specific disk encryption sets
  • Virtual machines should encrypt temp disks, caches, and data flows

Storage:

  • Storage accounts should use customer-managed key for encryption
  • Secure transfer to storage accounts should be enabled
  • Storage accounts should restrict network access
  • Public network access should be disabled for storage accounts

Networking:

  • Network interfaces should not have public IPs
  • Subnets should be associated with a Network Security Group
  • All Internet traffic should be routed via your deployed Azure Firewall
  • Network Watcher should be enabled

Security:

  • Azure Defender for servers should be enabled
  • Vulnerability assessment should be enabled on SQL servers
  • Diagnostic logs should be enabled in all services
  • Microsoft Antimalware for Azure should be deployed

Tags:

  • Require a tag and its value on resources
  • Inherit a tag from the resource group if missing
  • Add or replace a tag on resources

Cost Management:

  • Not allowed resource types
  • Allowed locations
  • Allowed virtual machine size SKUs

Azure Policy Initiatives

An initiative (also called a policy set) is a collection of policy definitions grouped together to achieve a specific compliance goal.

Why Use Initiatives?

Single initiatives can:

  • Group related policies for easier management
  • Track compliance for regulatory frameworks (PCI-DSS, HIPAA, ISO 27001)
  • Simplify assignments (assign one initiative instead of 50+ individual policies)
  • Provide aggregate compliance scores

Example: Enable Monitoring in Azure Security Center

This initiative contains 100+ policy definitions including:

SQL Security Policies:

  • Monitor unencrypted SQL Database in Security Center
  • Transparent Data Encryption on SQL databases should be enabled
  • An Azure Active Directory administrator should be provisioned for SQL servers
  • Auditing on SQL server should be enabled

VM Security Policies:

  • Monitor OS vulnerabilities in Security Center
  • Monitor missing Endpoint Protection in Security Center
  • System updates should be installed on your machines
  • Adaptive application controls should be enabled on virtual machines

Network Security Policies:

  • Monitor permissive network access in Security Center
  • Management ports should be closed on your virtual machines
  • Just-In-Time network access control should be applied on virtual machines

Storage Security Policies:

  • Monitor unencrypted Storage Account in Security Center
  • Storage accounts should restrict network access using virtual network rules
  • Storage accounts should use private link

Built-in Initiative Examples

1. PCI DSS 3.2.1

  • 298 policy definitions
  • Ensures Payment Card Industry compliance
  • Covers encryption, access control, monitoring

2. ISO 27001:2013

  • 345 policy definitions
  • Information security management standards
  • Comprehensive security controls

3. Azure Security Benchmark

  • 200+ policy definitions
  • Microsoft's security best practices
  • Covers all Azure services

4. HIPAA/HITRUST

  • 185 policy definitions
  • Healthcare data protection
  • Privacy and security requirements

Policy Assignment and Management

Creating Policy Assignments

Assignment Components:

Policy Assignment
├─ Policy Definition (what to enforce)
├─ Scope (where to enforce)
├─ Parameters (customization)
├─ Enforcement Mode (enabled/disabled)
├─ Remediation (fix existing resources)
└─ Exclusions (specific resources to skip)

Assignment Process

1. Via Azure Portal:

Azure Policy → Definitions → Select Policy → Assign
├─ Basics: Name, description, scope
├─ Parameters: Configure policy parameters
├─ Remediation: Create remediation tasks
├─ Non-compliance messages: Custom messages
└─ Review + Create

2. Via Azure CLI:

# Assign a policy to a resource group
az policy assignment create \
  --name 'audit-vm-managed-disks' \
  --display-name 'Audit VMs without managed disks' \
  --scope '/subscriptions/{subscription-id}/resourceGroups/{rg-name}' \
  --policy '/providers/Microsoft.Authorization/policyDefinitions/{policy-id}'

# Assign an initiative
az policy set-definition assignment create \
  --name 'pci-dss-3.2.1' \
  --display-name 'PCI DSS 3.2.1 Compliance' \
  --policy-set-definition '/providers/Microsoft.Authorization/policySetDefinitions/496eeda9-8f2f-4d5e-8dfd-204f0a92ed41' \
  --scope '/subscriptions/{subscription-id}'

3. Via Azure PowerShell:

# Assign policy to subscription
New-AzPolicyAssignment `
  -Name 'require-tag-on-rg' `
  -DisplayName 'Require CostCenter tag on resource groups' `
  -Scope '/subscriptions/{subscription-id}' `
  -PolicyDefinition $definition `
  -PolicyParameter @{'tagName'='CostCenter'}

# Assign initiative with remediation
New-AzPolicyAssignment `
  -Name 'enable-monitoring' `
  -PolicySetDefinition $initiative `
  -Scope $scope `
  -Location 'eastus' `
  -IdentityType 'SystemAssigned'

4. Via ARM Template:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "resources": [
    {
      "type": "Microsoft.Authorization/policyAssignments",
      "apiVersion": "2021-06-01",
      "name": "deny-public-ip",
      "properties": {
        "displayName": "Deny creation of public IPs",
        "policyDefinitionId": "/providers/Microsoft.Authorization/policyDefinitions/83a86a26-fd1f-447c-b59d-e51f44264114",
        "scope": "[subscription().id]",
        "enforcementMode": "Default"
      }
    }
  ]
}

Enforcement Modes

Default (Enabled):

  • Policy is fully enforced
  • Non-compliant operations are blocked (for Deny policies)
  • Compliance is evaluated and reported

DoNotEnforce (Disabled):

  • Policy is evaluated but not enforced
  • Non-compliant operations are allowed
  • Compliance is reported (Audit mode)
  • Useful for testing before enforcement

Example:

# Deploy policy in DoNotEnforce mode for testing
az policy assignment create \
  --name 'test-vm-policy' \
  --policy '/providers/Microsoft.Authorization/policyDefinitions/{id}' \
  --scope $scope \
  --enforcement-mode 'DoNotEnforce'

# After testing, enable enforcement
az policy assignment update \
  --name 'test-vm-policy' \
  --enforcement-mode 'Default'

Automatic Remediation

Azure Policy can automatically fix non-compliant resources using remediation tasks.

How Remediation Works

For Existing Resources:

Non-compliant resource detected
    ↓
Remediation task created
    ↓
Managed identity granted permissions
    ↓
DeployIfNotExists or Modify policy executes
    ↓
Resource becomes compliant

Remediation Example: Diagnostic Settings

Policy: "Deploy diagnostic settings for Azure SQL to Log Analytics"

Before Remediation:

  • 50 SQL databases exist
  • 0 have diagnostic settings enabled
  • Policy shows 100% non-compliance

After Remediation Task:

# Create remediation task
az policy remediation create \
  --name 'remediate-sql-diagnostics' \
  --policy-assignment '/subscriptions/{sub-id}/providers/Microsoft.Authorization/policyAssignments/sql-diagnostics' \
  --resource-group 'production-databases'

# Check remediation progress
az policy remediation show \
  --name 'remediate-sql-diagnostics' \
  --resource-group 'production-databases'

Result:

  • Diagnostic settings deployed to all 50 databases
  • Logs flowing to Log Analytics workspace
  • 100% compliance achieved

Remediation with Managed Identity

Policies that modify resources require a managed identity:

{
  "identity": {
    "type": "SystemAssigned"
  },
  "location": "eastus",
  "properties": {
    "displayName": "Configure diagnostic settings",
    "policyDefinitionId": "{policy-id}",
    "parameters": {
      "logAnalytics": {
        "value": "/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.OperationalInsights/workspaces/{workspace}"
      }
    }
  }
}

Required Steps:

  1. Policy assignment creates managed identity
  2. Grant identity appropriate RBAC roles
  3. Identity can now modify resources
  4. Remediation executes under identity's permissions

Policy Parameters

Parameters make policies reusable by allowing customization at assignment time.

Defining Parameters

Policy Definition with Parameters:

{
  "properties": {
    "displayName": "Allowed locations",
    "parameters": {
      "allowedLocations": {
        "type": "Array",
        "metadata": {
          "description": "The list of allowed locations for resources",
          "displayName": "Allowed locations",
          "strongType": "location"
        }
      }
    },
    "policyRule": {
      "if": {
        "not": {
          "field": "location",
          "in": "[parameters('allowedLocations')]"
        }
      },
      "then": {
        "effect": "deny"
      }
    }
  }
}

Using Parameters in Assignments

PowerShell:

$locations = @('eastus', 'westus')
$params = @{'allowedLocations' = $locations}

New-AzPolicyAssignment `
  -Name 'restrict-locations' `
  -PolicyDefinition $definition `
  -Scope $scope `
  -PolicyParameter $params

Azure CLI:

az policy assignment create \
  --name 'restrict-locations' \
  --policy '{policy-id}' \
  --params '{
    "allowedLocations": {
      "value": ["eastus", "westus"]
    }
  }'

Compliance Monitoring and Reporting

Viewing Compliance

Azure Portal:

Azure Policy → Compliance
├─ Overall Compliance Score: 78%
├─ Non-compliant Resources: 145
├─ Non-compliant Policies: 12
└─ Filter by:
    ├─ Subscription
    ├─ Resource Group
    ├─ Resource Type
    └─ Policy Assignment

Compliance Details:

  • Resource compliance: Which resources are non-compliant
  • Policy compliance: Which policies have violations
  • Compliance trends: Historical compliance data
  • Compliance reasons: Why resources are non-compliant

Querying Compliance Data

Azure Resource Graph:

// Find all non-compliant resources
PolicyResources
| where type == "microsoft.policyinsights/policystates"
| where properties.complianceState == "NonCompliant"
| project 
    resourceId = properties.resourceId,
    policyName = properties.policyDefinitionName,
    reason = properties.complianceReasonCode

// Count non-compliant resources by type
PolicyResources
| where type == "microsoft.policyinsights/policystates"
| where properties.complianceState == "NonCompliant"
| summarize count() by resourceType = tostring(properties.resourceType)
| order by count_ desc

Azure CLI:

# Get compliance summary
az policy state summarize \
  --resource-group 'production'

# List non-compliant resources
az policy state list \
  --filter "ComplianceState eq 'NonCompliant'" \
  --query "[].{Resource:resourceId, Policy:policyDefinitionName}"

Compliance Reporting

Generate Compliance Report:

# Export compliance data
Get-AzPolicyState `
  -Filter "ComplianceState eq 'NonCompliant'" |
  Export-Csv -Path 'non-compliant-resources.csv'

# Get compliance by policy
Get-AzPolicyStateSummary -Top 10 |
  Select-Object PolicyAssignmentName, 
                @{N='NonCompliant';E={$_.Results.NonCompliantResources}},
                @{N='Compliant';E={$_.Results.CompliantResources}}

Common Policy Scenarios

Scenario 1: Enforce Tagging Standards

Requirement: All resources must have CostCenter and Environment tags

Solution:

{
  "if": {
    "anyOf": [
      {
        "field": "tags['CostCenter']",
        "exists": "false"
      },
      {
        "field": "tags['Environment']",
        "exists": "false"
      }
    ]
  },
  "then": {
    "effect": "deny"
  }
}

Alternative with Auto-remediation:

{
  "if": {
    "field": "tags['CostCenter']",
    "exists": "false"
  },
  "then": {
    "effect": "modify",
    "details": {
      "roleDefinitionIds": [
        "/providers/microsoft.authorization/roleDefinitions/b24988ac-6180-42a0-ab88-20f7382dd24c"
      ],
      "operations": [
        {
          "operation": "add",
          "field": "tags['CostCenter']",
          "value": "[parameters('costCenterValue')]"
        }
      ]
    }
  }
}

Scenario 2: Restrict VM Sizes for Cost Control

Requirement: Limit VMs to cost-effective SKUs

{
  "if": {
    "allOf": [
      {
        "field": "type",
        "equals": "Microsoft.Compute/virtualMachines"
      },
      {
        "not": {
          "field": "Microsoft.Compute/virtualMachines/sku.name",
          "in": [
            "Standard_B2s",
            "Standard_B2ms",
            "Standard_D2s_v3",
            "Standard_D4s_v3"
          ]
        }
      }
    ]
  },
  "then": {
    "effect": "deny"
  }
}

Scenario 3: Ensure Encryption at Rest

Requirement: All storage accounts must use encryption

{
  "if": {
    "allOf": [
      {
        "field": "type",
        "equals": "Microsoft.Storage/storageAccounts"
      },
      {
        "not": {
          "field": "Microsoft.Storage/storageAccounts/encryption.services.blob.enabled",
          "equals": "true"
        }
      }
    ]
  },
  "then": {
    "effect": "deny"
  }
}

Scenario 4: Geographic Restrictions

Requirement: Resources only in approved regions

{
  "if": {
    "not": {
      "field": "location",
      "in": "[parameters('allowedLocations')]"
    }
  },
  "then": {
    "effect": "deny"
  }
}

Assignment:

az policy assignment create \
  --name 'restrict-to-us-regions' \
  --policy '{policy-id}' \
  --params '{
    "allowedLocations": {
      "value": ["eastus", "eastus2", "westus", "westus2", "centralus"]
    }
  }'

Scenario 5: Require SQL Auditing

Requirement: All SQL servers must have auditing enabled

{
  "if": {
    "field": "type",
    "equals": "Microsoft.Sql/servers"
  },
  "then": {
    "effect": "DeployIfNotExists",
    "details": {
      "type": "Microsoft.Sql/servers/auditingSettings",
      "name": "default",
      "roleDefinitionIds": [
        "/providers/microsoft.authorization/roleDefinitions/056cd41c-7e88-42e1-933e-88ba6a50c9c3"
      ],
      "deployment": {
        "properties": {
          "mode": "incremental",
          "template": {
            "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
            "contentVersion": "1.0.0.0",
            "parameters": {
              "serverName": {
                "type": "string"
              },
              "storageAccountName": {
                "type": "string"
              }
            },
            "resources": [
              {
                "type": "Microsoft.Sql/servers/auditingSettings",
                "apiVersion": "2021-02-01-preview",
                "name": "[concat(parameters('serverName'), '/default')]",
                "properties": {
                  "state": "Enabled",
                  "storageEndpoint": "[concat('https://', parameters('storageAccountName'), '.blob.core.windows.net')]",
                  "retentionDays": 90,
                  "auditActionsAndGroups": [
                    "SUCCESSFUL_DATABASE_AUTHENTICATION_GROUP",
                    "FAILED_DATABASE_AUTHENTICATION_GROUP",
                    "BATCH_COMPLETED_GROUP"
                  ]
                }
              }
            ]
          }
        }
      }
    }
  }
}

Policy Exemptions

Sometimes specific resources need to be excluded from policies.

Creating Exemptions

Valid Exemption Reasons:

  • Waiver: Resource is approved to violate policy
  • Mitigated: Compensating controls are in place

Example:

# Create exemption for a specific VM
az policy exemption create \
  --name 'legacy-vm-exemption' \
  --display-name 'Legacy VM Exemption' \
  --policy-assignment '/subscriptions/{sub}/providers/Microsoft.Authorization/policyAssignments/require-encryption' \
  --exemption-category 'Waiver' \
  --expires-on '2026-12-31' \
  --description 'Legacy VM scheduled for decommission in 2026' \
  --scope '/subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.Compute/virtualMachines/{vm}'

Best Practices:

  • Always set expiration dates on exemptions
  • Document the business justification
  • Review exemptions regularly (quarterly)
  • Minimize exemption usage
  • Require approval process for exemptions

Integration with Azure DevOps

Azure Policy integrates with CI/CD pipelines for policy-as-code.

Pre-deployment Validation

Azure Pipeline Task:

- task: AzureCLI@2
  displayName: 'Validate ARM Template Against Policies'
  inputs:
    azureSubscription: 'Production'
    scriptType: 'bash'
    scriptLocation: 'inlineScript'
    inlineScript: |
      # Export policies
      az policy assignment list --output json > policies.json
      
      # Validate template
      az deployment group what-if \
        --resource-group $(ResourceGroup) \
        --template-file $(TemplateFile) \
        --parameters $(ParametersFile)
      
      # Check for policy violations
      if [ $? -ne 0 ]; then
        echo "Template would violate policies"
        exit 1
      fi

Post-deployment Compliance Check

- task: AzurePowerShell@5
  displayName: 'Check Policy Compliance'
  inputs:
    azureSubscription: 'Production'
    ScriptType: 'InlineScript'
    Inline: |
      Start-Sleep -Seconds 60  # Wait for policy evaluation
      
      $nonCompliant = Get-AzPolicyState `
        -ResourceGroupName $(ResourceGroup) `
        -Filter "ComplianceState eq 'NonCompliant'"
      
      if ($nonCompliant.Count -gt 0) {
        Write-Error "Deployment resulted in non-compliant resources"
        $nonCompliant | Format-Table
        exit 1
      }

Best Practices

1. Start with Audit, Then Enforce

Phase 1: Audit (30 days)
└─ Identify non-compliant resources
└─ Understand impact

Phase 2: Test Enforcement (30 days)
└─ Use DoNotEnforce mode
└─ Validate with teams

Phase 3: Full Enforcement
└─ Enable Default mode
└─ Monitor compliance
❌ Don't: Assign 50 individual policies
✅ Do: Create initiative with 50 policies, assign once

3. Leverage Built-in Policies First

Before creating custom policies:
1. Search built-in definitions
2. Check community samples
3. Modify existing policies if needed
4. Create custom only if necessary

4. Implement Policy Hierarchy

Management Group (Broad policies)
├─ All resources must have tags
├─ All resources must use approved regions
└─ All resources must enable diagnostics

Subscription (Environment-specific)
├─ Production: High security, no public IPs
└─ Development: Relaxed, allow public IPs

Resource Group (Workload-specific)
└─ Database RG: Encryption required, backups enabled

5. Test Policies Thoroughly

# Test in non-production first
az policy assignment create \
  --name 'test-policy' \
  --scope '/subscriptions/{dev-sub-id}' \
  --policy '{policy-id}' \
  --enforcement-mode 'DoNotEnforce'

# Monitor for 1-2 weeks
az policy state list \
  --filter "PolicyAssignmentName eq 'test-policy'"

# Enable enforcement after validation
az policy assignment update \
  --name 'test-policy' \
  --enforcement-mode 'Default'

6. Document Everything

Policy Documentation Template:
├─ Purpose: Why this policy exists
├─ Scope: Where it applies
├─ Effect: What happens on violation
├─ Exceptions: Who can get exemptions
├─ Remediation: How to fix violations
└─ Contact: Policy owner

7. Regular Compliance Reviews

Weekly:
└─ Review new non-compliant resources

Monthly:
└─ Review overall compliance trends
└─ Update exemptions

Quarterly:
└─ Review and update policy definitions
└─ Audit exemptions
└─ Train teams on new policies

Annually:
└─ Complete policy portfolio review
└─ Align with regulatory changes
└─ Optimize policy assignments

Troubleshooting Common Issues

Issue 1: Policy Not Evaluating

Symptoms: Resources created but not evaluated

Solutions:

# Check policy assignment
az policy assignment show --name '{policy-name}'

# Verify scope is correct
# Check enforcement mode (should be "Default")

# Manually trigger evaluation
az policy state trigger-scan \
  --resource-group '{resource-group}'

Issue 2: Remediation Failing

Symptoms: Remediation task shows failures

Solutions:

# Check managed identity permissions
Get-AzRoleAssignment -ObjectId '{identity-object-id}'

# Grant required roles
New-AzRoleAssignment `
  -ObjectId '{identity-object-id}' `
  -RoleDefinitionName 'Contributor' `
  -Scope '{scope}'

# Retry remediation
Start-AzPolicyRemediation -Name '{task-name}'

Issue 3: Policy Blocking Legitimate Resources

Symptoms: Valid resources being denied

Solutions:

  1. Review policy parameters
  2. Create exemption if needed
  3. Modify policy definition if incorrect
  4. Use DoNotEnforce temporarily
# Create temporary exemption
az policy exemption create \
  --name 'temp-exemption' \
  --policy-assignment '{assignment}' \
  --exemption-category 'Waiver' \
  --expires-on '{date}' \
  --scope '{resource-scope}'

Policy as Code

Storing Policies in Git

Repository Structure:

policies/
├─ definitions/
│   ├─ compute/
│   │   ├─ allowed-vm-sizes.json
│   │   └─ require-managed-disks.json
│   ├─ storage/
│   │   └─ require-encryption.json
│   └─ networking/
│       └─ deny-public-ip.json
├─ initiatives/
│   ├─ security-baseline.json
│   └─ cost-optimization.json
└─ assignments/
    ├─ production.json
    └─ development.json

Deployment Pipeline

trigger:
  paths:
    include:
      - policies/*

pool:
  vmImage: 'ubuntu-latest'

steps:
- task: AzureCLI@2
  displayName: 'Deploy Policy Definitions'
  inputs:
    azureSubscription: 'Management'
    scriptType: 'bash'
    scriptLocation: 'inlineScript'
    inlineScript: |
      # Deploy definitions
      for file in policies/definitions/**/*.json; do
        az policy definition create \
          --name $(basename $file .json) \
          --rules $file \
          --mode Indexed
      done
      
      # Deploy initiatives
      for file in policies/initiatives/*.json; do
        az policy set-definition create \
          --name $(basename $file .json) \
          --definitions $file
      done
      
      # Create assignments
      for file in policies/assignments/*.json; do
        az policy assignment create \
          --name $(basename $file .json) \
          --policy-set-definition $(cat $file | jq -r '.policySetDefinitionId') \
          --scope $(cat $file | jq -r '.scope')
      done

Quick Reference

Common Azure CLI Commands

# List all policy definitions
az policy definition list

# Show specific policy
az policy definition show --name '{policy-name}'

# Create custom policy
az policy definition create \
  --name '{policy-name}' \
  --rules '{policy-rules.json}' \
  --params '{policy-params.json}'

# List policy assignments
az policy assignment list

# Check compliance
az policy state list --filter "ComplianceState eq 'NonCompliant'"

# Trigger policy scan
az policy state trigger-scan --resource-group '{rg-name}'

# Create remediation task
az policy remediation create \
  --name '{task-name}' \
  --policy-assignment '{assignment-id}'

# Delete policy assignment
az policy assignment delete --name '{assignment-name}'

Common PowerShell Commands

# Get policy definitions
Get-AzPolicyDefinition

# Create policy assignment
New-AzPolicyAssignment -Name '{name}' -PolicyDefinition $def -Scope '{scope}'

# Get compliance state
Get-AzPolicyState -Filter "ComplianceState eq 'NonCompliant'"

# Start remediation
Start-AzPolicyRemediation -Name '{task-name}' -PolicyAssignmentId '{id}'

# Get compliance summary
Get-AzPolicyStateSummary -ManagementGroupName '{mg-name}'

# Create policy exemption
New-AzPolicyExemption -Name '{name}' -PolicyAssignment $assignment -ExemptionCategory 'Waiver'

Policy Effects Quick Reference

EffectDescriptionUse Case
DenyBlocks resource creation/updatePrevent non-compliant resources
AuditLogs non-compliance, allows operationVisibility without blocking
AuditIfNotExistsAudits if related resource missingCheck for required configurations
DeployIfNotExistsAuto-deploys missing resourcesAutomatic remediation
ModifyChanges resource propertiesAuto-tagging, configuration fixes
DisabledPolicy not evaluatedTesting, temporary deactivation

Conclusion

Azure Policy is an essential governance tool that ensures your Azure environment remains compliant, secure, and cost-effective. By defining policies at appropriate scopes, leveraging built-in definitions, and implementing automatic remediation, you can maintain control over thousands of resources without manual oversight.

Key Takeaways:

  • Start with audit mode before enforcing policies
  • Use initiatives to group related policies for easier management
  • Leverage built-in policies and initiatives for common compliance frameworks
  • Implement policy hierarchy from management group to resource level
  • Enable automatic remediation to reduce operational overhead
  • Monitor compliance regularly and act on violations promptly
  • Integrate policies into CI/CD pipelines for proactive compliance
  • Document policies thoroughly and review exemptions regularly

Remember: Azure Policy is not about blocking developers—it's about providing guardrails that enable teams to move fast while staying compliant and secure.


Additional Resources

Official Documentation

Compliance and Regulatory

Advanced Topics

Tools and CLI

Community Resources

Learning Resources

Troubleshooting and Support