Enterprise Policy as Code (EPAC) — Managing Azure Policy Exemptions
Learn how to create, manage, and deploy Azure Policy exemptions using EPAC for compliant exceptions to your governance policies.
When implementing Azure governance at scale, you’ll inevitably encounter scenarios where certain resources need to be exempt from policy requirements. Rather than modifying or removing policies entirely, Azure Policy exemptions provide a controlled way to handle these exceptions. In this post, we’ll explore how to manage exemptions effectively using Enterprise Azure Policy as Code (EPAC).
What is a Policy Exemption?
A policy exemption is an exception to an existing policy assignment that allows specific resources, resource groups, or subscriptions to bypass policy requirements without modifying the underlying policy. Think of it as a controlled “get out of jail free” card for your governance rules.
EPAC manages exemptions the same way it handles assignments: as code in a Git repository. This approach ensures that every exception is traceable, reviewable, and repeatable - critical aspects of maintaining governance standards.
When Should You Use Exemptions?
There are two primary categories of exemptions:
Waiver
You consciously accept the risk of non-compliance. The resource doesn’t meet the policy requirements, but you have a valid business reason for not addressing it immediately.
Example: A temporary sandbox environment that doesn’t require mandatory tagging.
Mitigated
There’s a compensating control outside of Azure Policy. The policy check doesn’t apply because the risk is already addressed through alternative means.
Example: A legacy application with custom security controls that exceed policy requirements.
Step-by-Step Guide to Creating Exemptions
Step 1: Determine the Scope
First, identify the appropriate level for your exemption:
- Specific resource
- Resource group
- Subscription
- Management group
Remember: the more specific the scope, the better. Management group-level exemptions affect everything below them, which is rarely what you want.
Step 2: Find the Correct Assignment ID
Every exemption links to a specific policy assignment, so you need the complete assignment ID. You can construct this from the scope in your assignments file combined with the assignment name:
/providers/Microsoft.Management/managementGroups/<id>/providers/Microsoft.Authorization/policyAssignments/<name>
Alternatively, retrieve it using Azure CLI:
az policy assignment show \
--name "require-env-tag" \
--scope "/providers/Microsoft.Management/managementGroups/<id>" \
--query id
Step 3: Create the Exemption File
Exemptions belong in Definitions/policyExemptions/<pacEnvironment>/. Create a new .jsonc file with the following structure:
{
"$schema": "https://raw.githubusercontent.com/Azure/enterprise-azure-policy-as-code/main/Schemas/policy-exemption-schema.json",
"exemptions": [
{
"name": "cmp-exempt-sandbox-env-tag",
"displayName": "[cloudmartinpronk] Exemption – sandbox does not require an Environment tag",
"description": "The sandbox resource group is exempt from the mandatory Environment tag policy because this environment is temporary and non-production.",
"exemptionCategory": "Waiver",
"expiresOn": "2026-12-31",
"scope": "/subscriptions/<subscription-id>/resourceGroups/rg-sandbox",
"policyAssignmentId": "/providers/Microsoft.Management/managementGroups/<mg-id>/providers/Microsoft.Authorization/policyAssignments/require-env-tag",
"assignmentScopeValidation": "Default",
"metadata": {
"approvedBy": "Martin Pronk",
"approvedOn": "2026-03-02",
"ticket": "INFRA-1234"
}
}
]
}
Step 4: Set an Expiration Date
Always include the expiresOn field for Waiver exemptions. Without an expiration date, exemptions remain active indefinitely and become forgotten technical debt. Expiration dates force periodic review and revalidation of exceptions.
Step 5: Include Metadata
While not mandatory, the metadata block is strongly recommended. Include at minimum:
- Who approved the exemption
- Approval date
- A ticket number for audit trail
This information is invaluable during compliance reviews and audits.
Step 6: Deploy via Pipeline
Exemptions deploy through the same EPAC pipeline as assignments. After running Deploy-PolicyPlan and Deploy-RoleAssignments, the exemption becomes active in Azure. In the Azure Portal, the resource will appear as “Exempt” in compliance reports.
Important Considerations
-
Scope Alignment: Exemptions only work when the exemption scope falls within the assignment scope. A subscription-level exemption won’t affect a resource group-level assignment.
-
File Organization: You can include multiple exemptions in the
exemptionsarray within a single file. Group logically related exceptions together. -
Audit Visibility: Exemptions appear in Azure Policy compliance reporting, allowing auditors to see which resources are exempt and why.
Best Practices
- Be Specific: Use the narrowest possible scope for exemptions
- Document Thoroughly: Always include clear descriptions and metadata
- Set Expiration Dates: Force periodic review of temporary exemptions
- Use Consistent Naming: Adopt a naming convention for easy identification
- Regular Reviews: Periodically audit active exemptions to ensure they’re still necessary
Conclusion
Policy exemptions are a powerful tool for managing exceptions in your Azure governance strategy. When implemented through EPAC, they provide the perfect balance between flexibility and control. By treating exemptions as code, you maintain the same standards of review, approval, and auditability that apply to your policies themselves.
Remember: exemptions should be the exception, not the rule. Use them judiciously and always with proper justification and documentation.