Hey, Azure Guy!

Azure Policy at Scale, Part 5: The verdict

Written in a personal capacity. I work as a Microsoft Cloud Solution Architect, but this series is my own research and my own opinion. It is not an official Microsoft position.

Four parts of evidence come down to one decision, so this part is deliberately the shortest. Almost nothing here is argued from scratch. Where a claim was established earlier, the sentence links to the part that established it rather than making you read it again.

The research behind this part was carried out up to 28 August 2026, and every source quoted here was re-checked on 11 September 2026 before publication, with no changes found. This field moves, so check the sources rather than the date if you are reading later.

This part was meant to follow Part 4 within a few days. Personal circumstances delayed it by a fortnight.

The answer

Start at native ALZ policy governance when policy is part of the platform landing zone lifecycle. Introduce EPAC deliberately when Azure Policy becomes a separately managed governance product that needs capabilities the standard ALZ operating model does not offer.

That sequence is also Microsoft’s published advice, in a Note in the Azure Architecture Center’s Deploy Azure landing zones:

“Compare the life cycle and flexibility of the two approaches before you decide on what approach to use long term. Begin by evaluating the native policy management in the default implementation. If that implementation doesn’t meet your governance needs, then do a minimum viable product (MVP) or proof of concept by using EPAC. Compare options, validate your findings, and confirm your choice before you implement an approach because you can’t easily change policy governance methods after you establish them.”

What the Note does not give you is the reasoning. It sets an order of evaluation and warns that the decision is hard to reverse, and then it leaves the load-bearing phrase, “doesn’t meet your governance needs”, entirely to the reader.

That phrase is where the actual disagreement sits. In my own work with customers, colleagues and partners I get confident and contradictory answers to it, often from people with a good deal more Azure Policy scar tissue than I have, and quoting the documentation has never once ended one of those conversations. It tells you what order to look in, not what you are looking for.

So the four parts behind this one are not an attempt to show that the guidance is correct. They are an attempt to establish what it means in practice: which governance needs the standard ALZ operating model does not meet, on which engine, and how you could tell before you commit rather than two years in. Part 1 quotes the guidance in full, alongside the Cloud Adoption Framework’s separate recommendation, and shows where in the documentation it sits.

If you stop reading here, you have the answer. The rest is how to tell which side of it you are on.

What the four parts established

Part What it looked at What it settles
1 The question itself, and the layer model underneath it A feature bake-off answers the wrong question. The real one is whether Azure Policy has to become a separately operated product in your organisation
2 Every published support statement in the chain, quoted word for word Support is a property of individual layers, not of a brand. The real difference is the AVM module layer, and it is narrower than the argument people make
3 Where the policy content comes from, and how each path deploys it The content argument and the cleanup argument, both retired
4 A deliberate hunt for capabilities only EPAC has Six clean differentiators survive, and three more answers depend on whether you deploy with Bicep or with Terraform
5 This page What to do with all of that

First, which native path are you on?

Part 4 broke something I had treated as one thing. On three of the more interesting questions, “native ALZ can do that” is an incomplete sentence, because the answer depends on the engine.

If the requirement is On the current Bicep path On the current Terraform path
Adopting a policy estate that already exists I found no documented policy adoption or migration workflow Purpose-built migration tooling, scoped in its own documentation to the prior CAF Enterprise Scale implementation
Role assignments for a custom DeployIfNotExists policy you wrote Hardcoded per management group, and documented as not overridable Derived from the assignPermissions metadata, with controls to set and unset it
Updating a custom policy definition A documented manual procedure A library version bump and a normal apply

Answer this before anything else, because a reader on Bicep and a reader on Terraform should not leave this page with the same conclusion.

One caveat belongs with that table. Several rows that look like gaps in an operating model are AVM questions underneath: a pattern module exists and nothing in the operating model calls it, or it exists in one language and is still a proposal in the other. AVM moves on its own cadence and does not advance both surfaces together, which is why this whole comparison carries a date.

The questions that actually decide it

Six capabilities survived Part 4’s attempt to eliminate them, on both engines. Turned around, they become questions about your organisation rather than about the tools.

Ask yourself Why it points at EPAC
Do several teams hold policy authority over the same scope, and do they have to coexist without deleting each other’s work? pacOwnerId is an ownership protocol between teams. I found no documented native answer on either path
Do you manage policy across several Entra tenants from one repository? A tenant per pacEnvironment in one repository. No native equivalent found, in either language
Do exemptions need a lifecycle of their own, for expiry, cleanup and release, rather than being deployed once as resources? EPAC treats the exemption as a lifecycle, with expiry classification, stale cleanup and a release path of its own
Is your DeployIfNotExists estate too large to remediate by hand after each policy refresh? Remediation as a scheduled, tracked task. Both native paths prepare the identity and the permissions the shipped policy set needs, and neither packages task creation, scheduling or failure handling
Do you have to take authority over policy resources that something else created, and remove what nobody declared? full versus ownedOnly, with the ownership qualifications. Both native paths clean up their own prior output and neither goes looking
Do you manage policy in tenants you do not own, through Azure Lighthouse? EPAC handles delegated management, with the scaling limit it documents itself

These six are the clean cross-engine qualifiers, and they are qualifying questions rather than a score. There is no threshold and no weighting, and I deliberately have not built a matrix, because a total would imply a precision this evidence does not support. One yes with a real process, a named owner and an audit obligation behind it justifies more than five hypothetical ones. A material gap from the path-specific table above can qualify on its own as well, which is why that table comes first. If none of these is a yes, no path-specific gap is material to you, and the weaker packaging differences below do not matter to how you operate, the case for a second policy operating model becomes hard to make.

A seventh is worth naming separately because it is weaker than the six. EPAC packages compliance reporting, and neither Accelerator does. On the native side the current ALZ documentation recommends the Azure Governance Visualizer, which carries its own disclaimer about not being a Microsoft product. Packaged versus recommended is a real difference, but it is not the same as an absence.

If you answered yes to one of these, read what the capabilities cost before you decide. A PowerShell-native toolchain, the recommended epac-dev hierarchy, desired-state authority that is the capability and the risk at once, and breaking changes as a normal part of the deal. Every one of those is manageable and none of them is free.

One thing has become cheaper since I started. EPAC v11.0.0 lists “Changes to the ALZ sync process to support easier customization via a single file and not a forked repository”, covering ignored archetypes, custom management groups and per-assignment parameter overrides. Customising that synchronised content no longer means maintaining a fork of the ALZ Library repository, which lowers the price of the thing this page is asking you to justify.

Three criteria I left out

Organisation size on its own, because scale changes how much the capabilities above are worth, not whether you need them.

Existing team familiarity, because it is a real delivery and operational constraint rather than an architectural requirement. It belongs in your plan and your risk register, and on its own it does not establish that EPAC is required.

A stated preference for policy as code, which is the most common one I hear and the one that dissolves fastest on inspection. The AVM based Bicep and Terraform ALZ implementations already manage policy as code. Preferring policy as code does not distinguish between them.

Arguments that no longer decide it

These are the sentences people bring to the discussion. Each one is retired by evidence in an earlier part rather than by anything here.

The argument Where it stands as of 28 August 2026
“EPAC is unsupported, the native stack is supported” Not as usually stated. Support is per layer. AVM is officially supported Microsoft OSS with a documented CSS entry point, and most of the rest of the chain publishes GitHub Issues as its channel
“EPAC gives you better policies” Expired. Both routes consume the same library
“EPAC cleans up, the native path does not” Retired in its unqualified form. Both native paths have declarative removal, by mechanisms that are not EPAC’s
“Only EPAC shows you a plan before it applies” The platform gap closed on 18 August 2026. Whether an Accelerator has adopted it is a separate question, and I found no evidence it had
“Only EPAC can deploy exemptions” The resource is not the point. An AVM Bicep pattern module is published and its Terraform counterpart is a proposal. The process around exemptions is what survives
“EPAC lets you test policies” Neither operating model productises testing. The stronger documented pattern is published by ALZ, and I could not find a route that delivers it into a customer repository
“EPAC versions custom policies properly” It splits in two. The convention belongs to current ALZ guidance, which publishes one where EPAC does not. The update automation is EPAC’s
“The native path cannot adopt what already exists” Asymmetric, and the answer depends on your engine. See the table above
“We are too big for native” or “we already know EPAC” Neither is an architecture argument

Where the research went against my expectations

Part 1 said this series would be worth reading only if I published the findings that cut against my expectations. Three did, and not all in the same direction.

I expected native ALZ to be thin on custom policy authoring, versioning and testing. Current ALZ guidance publishes a fuller custom policy versioning convention than EPAC does, and publishes the stronger documented testing pattern of the two. Neither of those is what I predicted.

I expected the support argument to collapse entirely. It did not. AVM is a genuinely supported module layer with a documented CSS entry point, and that is a real difference from EPAC. It is narrower than the argument people make, and it is not nothing.

What survived is smaller than I expected, and it survived on the Bicep side specifically: updating a custom policy definition is a manual procedure in ALZ’s own documentation, and that is precisely the operational friction EPAC removes.

The hypothesis itself came through intact. Part 1 asked for a named, concrete requirement before reaching for EPAC, and said openly that Part 4 would go looking for cases that qualify. Part 4 found six. A hypothesis that survives a deliberate attempt to break it is doing its job.

Decide it early, and write down why

The most practical sentence in the whole comparison is Microsoft’s, not mine: “you can’t easily change policy governance methods after you establish them.”

The larger risk is not the migration itself. It is that the decision hardens into the operating model quietly, while nobody is looking at it, and the reasoning behind it leaves with whoever made it. So make it deliberately, record which of these questions you answered yes to, and record what would have to change for the answer to change. That record is worth more in two years than the decision itself.

The guidance exists, and it is still hard to land on

Part 1 said the guidance is not missing but is easy to miss, and that still holds. It is a Note inside a subsection of an article about deploying landing zones, under Variants and specializations, sitting alongside the sovereign landing zone variant and partner implementations rather than among the standard deployment options. A practitioner comparing two policy tools is unlikely to start there. The Cloud Adoption Framework separately recommends considering EPAC, in Enforce cloud governance policies under Use policy as code.

I had assumed the two sides did not point at each other, and I was wrong, which I only found because I went back to check my own working before writing this. EPAC’s front page links that Architecture Center article twice through a shortlink, and one of those links sits on the sentence recommending the ALZ implementation to teams with lower CI/CD maturity. My earlier search had extracted full learn.microsoft.com URLs and could not see a shortened one.

What I did find, on 28 August 2026 and again on 11 September 2026, is an asymmetry. In the Azure Landing Zones documentation repository, Azure/Azure-Landing-Zones, I found no mention of EPAC at all. That is an absence of documentation in one repository on the days I checked, not a statement about the wider ALZ material, and I have not extended the search to the Accelerators or to AVM.

So the ask is not “link the guidance”, because one side already does. It is that a practitioner choosing between two policy operating models has no obvious page to land on, and that surfacing the decision where the decision is actually made would help more than anything else in this series. I have no view on why it sits where it does.

My own position, as opinion

Everything above is evidence. This section is not, and I have kept it separate on purpose.

I default to native ALZ policy governance. Not because EPAC is weak, and I want to be exact about that: it is well-engineered, actively maintained, ships frequently, and is built by people who understand this domain deeply. I default to native because EPAC is a second operating model, and second operating models need justifying rather than assuming. A capability you can name is a justification. A preference is not.

The fairest thing in this entire comparison comes from EPAC’s own documentation, which routes part of its own audience elsewhere: “If your DevOps (CI/CD) maturity is lower, Azure Landing Zones direct implementation of Policies might be a better choice.” A project willing to write that has earned a careful reading in both directions.

There is also a criterion that rarely makes it into an evaluation. The question is not only which option is stronger today, but which one your organisation can still operate after the person who championed it moves on. Whichever way this goes, the operational ownership is yours, because on the evidence of the published support statements most of this chain documents GitHub Issues as its support channel.

What would change my mind

  • A documented support tier for EPAC beyond GitHub Issues, with a published response commitment.
  • The native path closing the multi-tenant or multi-owner gap on either engine.
  • A published native-path implementation of the six capabilities in Part 4’s table.
  • A concrete customer scenario this series has not accounted for. That invitation is open, and it is the one I would most like to receive.

And four things I have not finished checking, carried forward from Part 4 rather than quietly dropped now that a conclusion would be more comfortable without them:

  • Whether the Terraform state importer works against a policy estate with no CAF Enterprise Scale heritage at all.
  • Whether any documented means exists for a Deployment Stack to adopt a pre-existing resource.
  • Whether any documented route delivers the ALZ policy testing framework into a customer repository.
  • Whether anyone has published a native-path implementation of the six capabilities above.

None of those is resolved by this part, and none of them should be assumed either way.

Closing

There is no winner here, and a series that argued for five parts that this is a choice between operating models would undo itself by declaring one in the last paragraph.

What there is, is a boundary. On one side, policy is part of how you build and maintain landing zones, and the native path handles it. On the other, policy is a governed product in its own right, with owners, exemption processes, remediation schedules, audit reporting and often more than one tenant, and EPAC is built for that. Most organisations I meet are on the first side and assume they are on the second.

Work out which side you are on, using the six questions rather than a feature list. Then write down why, because the next person to ask will not have the benefit of the conversation you just had.

Revision log

  1. Corrected two things on the day of publication. I named the repository behind the EPAC absence search as the ALZ Library, when the repository I actually searched was Azure/Azure-Landing-Zones, which holds the ALZ documentation rather than the library assets. And the remediation row said both native paths create the identity and stop there, which understates them: both also arrange the role assignments the shipped ALZ policy set needs, and the EPAC differentiator starts at remediation task creation, scheduling and failure handling. Also clarified that the six questions are the clean cross-engine qualifiers rather than the only ones that can qualify, narrowed the exemption and EPAC v11 wording to what the sources establish, and softened two statements that had outrun their evidence. The verdict is unchanged.