azure | AZ-104AZ-305 | | 2 views

Azure Policy Fundamentals: Governance Disciplines, Definitions, and Compliance

  • azure-policy
  • compliance
  • management-and-governance

Azure Policy is the mechanism that turns "we agreed on a rule" into something Azure actually enforces, rather than something that lives in a wiki page and quietly drifts out of date. Before getting hands-on with writing one, it's worth understanding what it's actually for and how the pieces — definitions, assignments, effects, compliance — fit together.

The five disciplines of cloud governance

Cloud governance in general breaks down into five core disciplines, and Azure Policy is one of the main tools for enforcing several of them:

1) Cost management: evaluating and monitoring cost, controlling IT expenditure, and adjusting resources to demand, so cloud spend actually delivers value. 2) Security baseline: ensuring every adoption effort complies with IT security requirements. 3) Resource consistency: keeping resource configuration consistent and enforcing practices for onboarding, recovery, and discoverability. 4) Identity baseline: consistently applying role definitions and assignments so identity and access stay within agreed boundaries. 5) Deployment acceleration: accelerating policy deployment itself through centralisation, consistency, and standardised templates.

Adopting all five simplifies compliance and improves both the security and efficiency of a cloud environment — which is the underlying reason Azure Policy exists as a distinct service from Azure RBAC, rather than being folded into it (more on that distinction in the Policy vs. RBAC post in this series).

Definitions, assignments, and effects

Azure Policy lets you create, deploy, and manage policies to enforce organisational standards and assess compliance at scale. A policy definition is the core logic — the condition to evaluate and the effect to apply if a resource matches it — written as a JSON document. Azure ships hundreds of built-in definitions, and custom ones are just as valid.

A policy assignment applies a definition to a specific scope, determining where and when it takes effect. Assignments can target the Tenant Root Group (the root management group created for a tenant — not the Microsoft Entra tenant object itself, which isn't a Resource Manager scope in its own right), any other management group, a subscription, a resource group, or an individual resource, with each level inheriting from its parent. Exclusions (via the assignment's notScopes property) work at every one of those levels except the Tenant Root Group — you can exclude any other management group beneath it, but not the root group itself.

The effect determines what happens to a non-compliant resource. The common ones: Deny prevents the resource being created or updated at all, Audit logs the non-compliance without blocking anything, and Modify automatically changes the resource to bring it into compliance.

An initiative groups related policy definitions together under one larger governance goal, letting you assign several policies in a single action rather than one at a time — the practical unit of assignment once a governance programme grows past a handful of individual policies.

Exemptions

Sometimes a resource genuinely shouldn't be evaluated against a policy or initiative, temporarily or permanently — that's what the Policy exemptions feature is for, exempting either an individual resource or a whole resource hierarchy from evaluation. An exempted resource still counts toward overall compliance figures, it's just not evaluated (or is given a temporary waiver). Exemptions are created as a child object on the resource or hierarchy they apply to, and — unlike an excluded scope — they're created after assignment, not as part of it, though the practical effect on evaluation is the same.

Exemptions fall into two categories: Mitigated, where the policy's underlying intent is already satisfied through some other method, and Waiver, where the resource's non-compliance is being temporarily accepted rather than fixed. An exemption can also be set to expire automatically on a schedule via its expiresOn property, so a waiver doesn't quietly become permanent by default.

Attestations and remediation

Attestations set the compliance state for resources or scopes targeted by a manual policy effect — one that can't be evaluated automatically, so a person has to assert compliance instead. Each applicable resource needs one attestation per manual policy assignment, which is why manual policies are best designed to target a scope that already matches the natural boundary of what needs attesting, rather than forcing a lot of granular, repetitive attestations.

Remediation brings existing non-compliant resources into line with a modify or deployIfNotExists definition, either through a remediation task run against resources that already exist, or automatically for resources that are newly created or updated after the assignment is in place.

Some concrete things Azure Policy is commonly used to enforce: restricting deployments to allowed regions, enforcing geo-replication for data residency, limiting which VM sizes can be deployed, requiring consistent tagging, recommending server updates, requiring multi-factor authentication, and requiring diagnostic logs to flow to an Azure Monitor Logs workspace.

If a custom recommendation needs to surface inside Microsoft Defender for Cloud specifically, the RemediationDescription field goes in the policy definition's metadata.securityCenter property (alongside a Severity value) — that's a Defender for Cloud integration detail, not a requirement for policies generally.

When Azure Policy evaluates resources

Evaluation is triggered by several distinct events, not just a fixed schedule: a policy or initiative being newly assigned to a scope, an existing assignment being updated, a resource being deployed or updated within an assigned scope (through the portal, REST API, or an SDK), a subscription being created or moved within a management group hierarchy that has an assignment targeting subscriptions, a policy exemption being created, updated, or deleted, the machine configuration resource provider reporting new compliance details, an on-demand scan, and the standard compliance evaluation cycle.

That standard cycle runs automatically every 24 hours. For brownfield scenarios — applying a new policy to resources that already exist, rather than to new deployments — that daily cycle might not be fast enough to confirm a change took effect, so a manual scan can be triggered on demand with az policy state trigger-scan.

Compliance states

Once a policy or initiative is assigned, Azure Policy determines which resources it actually applies to, then evaluates every one that isn't excluded or exempted, assigning each a compliance state:

Non-compliant, Compliant, Error (a template or evaluation error), Conflicting (two or more assignments in the same scope with contradictory rules — for example, two policies each trying to append the same tag with a different value), Protected (covered by an assignment using a denyAction effect), and Exempted or Unknown (the default for definitions using the manual effect before an attestation is made).

Where a resource or an overall assignment could plausibly land in more than one of these states, Azure Policy ranks them in the order listed above and reports the higher-ranked one. The compliance percentage itself is calculated as compliant + exempt + unknown + protected resources, divided by the total (which additionally includes non-compliant, conflicting, and error resources).

Enforcement mode and safe deployment

enforcementMode is a property on the assignment itself, separate from the policy's effect, that lets you disable a policy's enforcement — Deny or Modify, for example — without disabling evaluation. With enforcement disabled, you see exactly what the policy's compliance outcome would be against existing resources, without it actually blocking anything or writing to the Activity log — a genuine "what-if" test, distinct from the disabled effect, which stops evaluation from happening at all.

Rolling out policy against a production environment without this kind of testing is a good way to break something you didn't intend to touch. The safe-deployment approach has two parts: start new assignments with enforcementMode disabled so you can see the compliance outcome before anything is enforced, and deploy in rings — starting with test and development environments, then a small production subset, then gradually the full estate — rather than assigning to everything at once. Treating policy definitions as code (source-controlled, tested, and validated on every change) is what makes this repeatable rather than a one-off manual check.

Sources