Azure Policy¶
The landing zone governs itself with Azure Policy. One module, the ALZ pattern module, builds the whole management group hierarchy and assigns the policy that governs every subscription placed into it. This section explains how that policy is put together and the two layers where you customize it.
This is Azure Policy, the platform's preventive and detective governance. It is a different thing from the policy, security, and cost gates, which run conftest, checkov, and infracost against a Terraform plan in a pull request. The gates check code before it applies. Azure Policy governs resources once they exist.
How policy reaches a management group¶
All of it flows through a single unit in the landing-zone repository,
_foundation/landing-zones/, which sources Azure/avm-ptn-alz/azurerm. The module
reads a library through the alz provider, builds the management groups from an
architecture, and assigns policy to each group from the archetypes attached
to it.
flowchart LR
L[ALZ library<br/>definitions, sets,<br/>assignments, archetypes,<br/>architecture] -->|alz provider<br/>library_references| P[avm-ptn-alz]
P --> H[Management group<br/>hierarchy]
P --> A[Policy assignments<br/>on each MG]
M[policy_assignments_to_modify<br/>policy_default_values] -.tune.-> A
The library is layered. The provider reads the stock Azure Landing Zones library
first, then your own library on top. The reference implementation vendors its
library into the landing-zones unit at lib/ and points the provider at it with
get_terragrunt_dir(), so there is no external dependency to resolve at plan time:
provider "alz" {
library_overwrite_enabled = true
library_references = [
{ path = "platform/alz", ref = "2026.04.2" },
{ custom_url = "${get_terragrunt_dir()}/lib" },
]
}
A git reference to a shared catalog is the alternative when you want one library
across many repos: { custom_url = "git::https://github.com/<org>/<catalog>.git//library/<path>?ref=<tag>" }.
References are read in order, so your library comes last and wins.
library_overwrite_enabled lets one of your assets replace a stock asset of the
same name. Everything in the combined library must be uniquely named otherwise.
What lives where¶
| Piece | Location | Owns |
|---|---|---|
| Module consumption and live tuning | the landing-zone repo, _foundation/landing-zones/main.tf |
Which assignments to modify, and the default values fed to them. |
| Provider and library pin | the same unit's terragrunt.hcl |
The stock library ref and the local lib/ path (or a git catalog ref). |
| Your custom library | vendored in the unit at landing-zones/lib/ (or a shared catalog repo) |
Your architecture, archetypes, and your own definitions, sets, and assignments. |
The two customization layers¶
There are two places to change policy, and the right one depends on what you are changing.
| Layer | Where | Use it to |
|---|---|---|
| In-repo tuning | policy_assignments_to_modify and policy_default_values in landing-zones/main.tf |
Change parameters, effects, enforcement mode, non-compliance messages, scope exclusions, or disable a single assignment. Fast, no library release. |
| In-library authoring | the vendored lib/ (or your shared catalog, then bump its ref) |
Add or replace a policy definition, an initiative, an assignment, an archetype, or reshape the management group hierarchy. |
Reach for in-repo tuning first. It needs no library release and it is the module's designed seam for per-tenant differences. Author in the library when the change is structural or you want it to ship to every client that consumes the library.
The recipes for both are in Customizing policies.
The reference baseline¶
Out of the box the stock archetypes assign the Microsoft cloud security benchmark and the ALZ policy set to the intermediate root, and the corp, online, and platform archetypes layer their own assignments below.
The starter library ships one worked example on top of that: a tag-governance
archetype attached to the intermediate root, which assigns a baseline tagging
strategy (mandatory tags on resource groups with allowed values, and tag
inheritance from subscription and resource group). Its tag keys follow the
Microsoft Cloud Adoption Framework tag examples
(app, env, opsteam, costcenter, businessunit, criticality,
confidentiality). Treat it as the template for your own controls: adapt the tags,
values, and scope per client.
The example effects start in Audit and move to Deny once the estate is clean.
That advisory-first rollout is a deliberate governance pattern, and it maps to the
CAF Govern methodology (policy-driven guardrails introduced without blocking
existing workloads) and the WAF Operational Excellence pillar (change landed
safely). Moving to Deny then serves WAF Security and Cost Optimization,
since untagged and misclassified resources are prevented rather than reported.
Next: Customizing policies.