An Azure Policy assignment is a JSON-driven rule that the platform evaluates against every in-scope resource and reports back as compliant, non-compliant, or exempt [1]. It is the mechanism Azure administrators rely on to stop configuration drift from quietly pulling a subscription out of alignment with internal standards or regulatory baselines. What follows walks the full pipeline end to end — planning scope, authoring or selecting definitions, grouping them into initiatives, assigning at the right level, wiring up remediation, and reading compliance results across the portal, CLI, and Resource Graph. The end state is a working governance loop across a management group hierarchy.

Prerequisites

A few things need to be in place before any of the steps below make sense.

The tenant needs a management group hierarchy with subscriptions placed inside it. Policy can be assigned at the management group, subscription, or resource group level, but evaluation only occurs at the subscription or resource group level [1].

On identity, the operator needs the Resource Policy Contributor built-in role on the target scope, which covers most authoring and assignment operations [1]. A second role, User Access Administrator, is required separately to grant the managed identity used by modify and deployIfNotExists assignments [1]. Without that grant, remediation tasks fail silently — and they tend to do so without an obvious error in the portal.

Install Azure CLI or Azure PowerShell with the Az.PolicyInsights module so on-demand scans, exports, and remediation can run from script. For hybrid scope, register Azure Arc-enabled servers and Kubernetes clusters so the same policies extend off-Azure [1].

Know the per-scope ceilings before designing anything: 500 policy definitions, 200 initiative definitions, and 200 assignments per scope [1]. Those numbers feel generous until a mature tenant runs into them.

Step 1 — Plan the Governance Scope and Definition Strategy

Decide what to govern and where the rule should attach before opening the portal. Map the management group, subscription, and resource group hierarchy on paper. A policy assigned high in the tree cascades to every resource beneath it, so a rule attached at the root management group automatically covers every subscription that joins later.

Next, choose the policyType to work with. Microsoft provides three: Builtin for the curated catalog, Custom for definitions an organization writes itself, and Static for the Microsoft-managed Regulatory Compliance controls that surface in the portal as "Microsoft managed" [3]. Most rollouts mix all three.

Pick the mode. The value all evaluates resource groups, subscriptions, and every resource type, while indexed evaluates only resource types that support tags and location [3]. Every policy authored through the Azure portal uses all by default [3].

Plan parameterization up front. A single definition supports a maximum of 20 parameters [1]. Anything you may want to vary per assignment — allowed SKUs, regions, tag keys — has to be a parameter.

Finally, choose the definition's location. It must live in a management group or a subscription, and that location sets the scope at which the policy can be assigned [3]. Putting custom definitions at the tenant root management group is the standard pattern, and it avoids the pain of relocating them later.

Step 2 — Author or Select Policy Definitions

A policy definition is a JSON document with required elements: displayName, description, mode, version, metadata, parameters, and policyRule [3]. The policyRule itself carries the logical evaluation (an if block) and the effect to apply when the rule matches.

Length limits matter at scale. displayName is capped at 128 characters, description at 512 characters, and each metadata property at 1,024 characters [3]. Definitions that breach these limits fail to save — quietly enough that the first sign of trouble is often a CI pipeline error.

The effect is the most consequential choice. Azure Policy supports addToNetworkGroup, append, audit, auditIfNotExists, deny, denyAction, deployIfNotExists, disabled, manual, modify, and mutate [4]. Order of evaluation runs disabled first, then append and modify, then deny, then audit, manual, and auditIfNotExists, and finally denyAction [4]. After the Resource Provider returns a success code, auditIfNotExists and deployIfNotExists run to decide whether additional logging or deployment is required [4].

Best practice is to start every new rule in audit or auditIfNotExists mode [1]. Watch what would have been blocked or remediated for a real evaluation cycle, then graduate to deny, modify, or deployIfNotExists only after the impact is well understood. This is the single rule that prevents a governance rollout from breaking production.

For most regulated workloads, search the built-in catalog first. Microsoft maintains hundreds of vetted definitions covering tags, encryption, networking, identity, and resource SKUs. Copying a built-in into a custom definition is worth doing only when a parameter or condition genuinely needs to change.

Step 3 — Group Definitions into an Initiative

A policy initiative — also called a policySet — bundles related definitions so they are managed and assigned as one object [1]. Microsoft recommends creating an initiative even when the rollout starts with a single policy, because adding more policies later does not multiply the number of assignments to track [1].

An initiative can contain up to 1,000 policy definitions and 400 parameters [1]. That ceiling is high enough to hold a complete regulatory baseline in a single object.

Inside the portal, each policy parameter in an initiative resolves in one of three ways: a Default value the policy ships with, a Set value hard-coded by the initiative, or a Use Initiative Parameter binding that exposes the value at assignment time [6]. The third option is what lets one initiative serve multiple teams with different allowed regions or tag schemes.

For regulatory work, lean on the built-in Regulatory Compliance initiatives. Microsoft ships full mappings for the Microsoft cloud security benchmark, NIST SP 800-53, ISO 27001, PCI DSS, HIPAA HITRUST, and more, organized by control and compliance domain with responsibility marked as Customer, Microsoft, or Shared [5]. Microsoft-responsible controls carry a policyType of static, and their results come from third-party attestation audits of the underlying infrastructure rather than customer resource evaluation [5].

Customers can copy a built-in Regulatory Compliance initiative, customize the included controls, and link the custom version to Microsoft Defender for Cloud so the compliance dashboard reflects the tailored baseline [5].

Step 4 — Assign the Initiative at the Target Scope

Assignment is where a definition becomes enforceable. In the portal, open Policy, choose Assignments, then Assign initiative — or Assign policy for a single definition. The wizard walks through scope, exclusions, parameters, remediation, and review [6].

Pick the scope first. Available choices are a management group, a subscription, or a resource group [6]. Remember the evaluation rule: a policy assigned at the management group level still only applies to resources sitting in subscriptions or resource groups beneath it [1].

Configure exclusions where needed. The notScopes field on an assignment removes specific subscriptions, resource groups, or resources from enforcement [6]. Each assignment supports up to 400 exclusions [1]. These are the right tool for explicit carve-outs — a sandbox subscription that should not inherit production controls, for example.

Resolve parameters. Any value the initiative exposes is set here. This is also where the custom non-compliance message that appears when a resource is denied or flagged gets supplied [6].

Toggle Policy enforcement. It defaults to Enabled. Setting it to Disabled assigns the rule and lets evaluation run, but suppresses the actual effect [6]. This is the safest way to test a deny policy in production before it starts blocking deployments.

Understand the layering rule before stacking assignments. The net effect across multiple overlapping assignments is cumulative most-restrictive — if any assignment denies a resource, the deployment is blocked [4]. There is no override hierarchy.

Step 5 — Configure Remediation, Managed Identity, and Exemptions

Any assignment that uses modify or deployIfNotExists needs an identity that can actually change resources. The wizard creates a System Assigned managed identity automatically and grants it Contributor on the assignment scope [6]. That grant is only possible if the operator running the assignment holds User Access Administrator rights on the scope [1].

For existing non-compliant resources, run a remediation task. A single task can target up to 50,000 resources [1]. The task uses the managed identity to apply the modify or deployIfNotExists template to every matching resource that was already in place when the assignment took effect.

When a specific resource needs to bypass a rule, prefer a policy exemption over a notScopes exclusion. Creating, updating, or deleting an exemption immediately re-evaluates the assignment for the exempted scope [2]. Each scope supports up to 1,000 exemptions [1]. Exemptions also carry their own metadata fields for justification and category, which makes them auditable in a way that broad notScopes carve-outs simply are not.

Step 6 — Verify Compliance Reporting and Iterate

Compliance evaluation runs on a predictable schedule, and the numbers matter.

A newly assigned or updated policy takes about five minutes to apply at its scope before the evaluation cycle begins [2]. After that, when a resource is created or changed inside an assigned scope, its effect event and compliant status appear in the portal and SDKs around 15 minutes later [2]. A subscription that is created or moved inside a management group hierarchy is evaluated against subscription-targeted assignments about 30 minutes after the move [2]. The standard background cycle re-evaluates every assignment once every 24 hours [2].

Reporting surfaces are layered. The Policy Overview page shows compliance state and counts per assignment with a chart covering the last seven days [2]. The Compliance page lists every policy and initiative; selecting one opens a Resource compliance tab that defaults to all states with filters for compliant, non-compliant, conflicting, and exempt resources [2]. Right-clicking a row and choosing Show activity logs opens the Activity log already filtered to that assignment [2].

For an off-cycle check, trigger an on-demand scan. This can be invoked through the REST API, Azure CLI, Azure PowerShell, the Azure Policy VS Code extension, or the Azure Policy Compliance Scan GitHub Action [2]. On-demand scans are the right answer when a stakeholder wants confirmation faster than the 24-hour cycle allows.

For dashboards beyond what the portal offers, query the Microsoft.PolicyInsights resource provider directly. PolicyStates returns evaluation results, with the special latest value scoping the query to the last 24 hours, and PolicyEvents returns the change history [2]. Compliance records are also stored in Azure Resource Graph, and Microsoft publishes sample queries that can be wired into a Workbook or Grafana board [2].

Troubleshooting and Common Issues

A handful of failure modes show up repeatedly during rollout.

A deployment blocked by a deny effect surfaces in the target resource group's Deployments view with a Forbidden status, and the underlying policy event lives under the Events tab of the initiative's Compliance page [6]. Check both views before assuming the failure is unrelated to policy.

Missing remediation results almost always trace back to identity. If the managed identity was created without the User Access Administrator grant in place, it cannot write to the target resources [1]. The remedy is to re-run the role assignment, not to redeploy the policy.

Resources that never seem to evaluate may sit inside the Microsoft.Resources provider, which is excluded from policy evaluation by design — the explicit exceptions are subscriptions and resource groups themselves [2]. Management-group-only assignments produce no compliance data on the management group object, only on the subscriptions and resource groups beneath it [1].

Two hard ceilings cause silent rejection during authoring: the request body cannot exceed 1,048,576 bytes, and a policy rule cannot exceed 512 nested conditionals [1]. When either limit hits, split the definition or refactor the condition tree.

Finally, the Static (Microsoft managed) controls inside Regulatory Compliance initiatives will always show Microsoft-attested results rather than customer evaluation [5]. That is by design, not a reporting bug.

Conclusion: Building the Governance Loop

Azure Policy governance is a five-move loop: define, group, assign, remediate, report. Start every rule in audit mode, graduate to enforcement once the real-world impact is known, and extend coverage to hybrid resources with Azure Arc and to custom dashboards with Resource Graph. The next step for any team adopting this pipeline is to wire the on-demand scan and PolicyStates queries into a CI gate so non-compliant resources never reach production in the first place.

Sources

  1. Overview of Azure Policy - Azure Policy | Microsoft Learn
  2. Get policy compliance data - Azure Policy | Microsoft Learn
  3. Details of Azure Policy definition structure basics - Azure Policy | Microsoft Learn
  4. Azure Policy definitions effect basics - Azure Policy | Microsoft Learn
  5. Regulatory Compliance in initiative definitions - Azure Policy | Microsoft Learn
  6. Tutorial: Build policies to enforce compliance - Azure Policy | Microsoft Learn