Every platform team that reaches a certain scale ends up asking the same question: do we keep hand-rolling our own Bicep or Terraform modules, or do we standardize on something maintained outside the team? Azure Verified Modules (AVM) is Microsoft’s answer to that question — a library of Microsoft-owned, Well-Architected-Framework-aligned modules for both Bicep and Terraform, consolidating what used to be fragmented efforts (CARML on the Bicep side, various community-maintained “verified” modules on the Terraform side) into one specification-driven catalog.
For teams building landing zones specifically, this isn’t a peripheral tooling decision. The Azure Landing Zone reference architecture itself is assembled from a handful of AVM pattern modules behind the scenes. So the question isn’t really “should we look at AVM” — it’s “how much of our platform should be built on top of it, and where do we still need our own layer.”
What AVM actually is, briefly
AVM organizes modules into three classifications, and the distinction matters for how you’ll actually use them:
- Resource modules map one-to-one to a single Azure resource type — a storage account, a virtual network, a Key Vault. Need ten of something, you loop the module.
- Pattern modules compose multiple resource modules into a larger architectural slice — this is the level at which things like landing zone subscriptions get assembled.
- Utility modules are helpers you rarely call directly — region lookups, SKU availability checks, naming convention enforcement.
Every module, regardless of classification, is built against a shared specification: consistent interface conventions, mandatory documentation generation, automated testing, and alignment with Well-Architected Framework recommendations. That specification is the actual product here — the modules are just the implementation of it.
What you gain
You stop relitigating “what does a good module look like.” Every platform team eventually has this argument internally — output naming conventions, parameter structure, how much flexibility to expose versus lock down. AVM’s specification already answers most of it, developed and iterated on by a team with visibility across the entire Azure resource surface, not just your organization’s slice of it.
Well-Architected Framework alignment is the default, not a checklist item. Instead of every team (or every module author on your team) independently re-deriving what “secure by default” or “reliable by default” means for a given resource, that judgment is already encoded upstream.
Consistency across Bicep and Terraform lowers the cost of supporting both. If your organization is running a mixed IaC estate — which is increasingly common as teams explore Terraform/OpenTofu alongside a Bicep-first history — AVM’s shared conventions mean the mental model transfers between languages even when the syntax doesn’t.
Faster bootstrapping for new landing zone components. A meaningful share of what an enterprise landing zone needs — networking primitives, monitoring, identity scaffolding — already has a tested, documented AVM equivalent. That’s less of your team’s time spent on generic infrastructure and more available for the parts that are actually specific to your organization.
What you give up
Release cadence and breaking-change timing aren’t yours to control. When Microsoft ships a breaking change to a module you depend on, it lands on their schedule, not your change-management calendar. At landing zone scale, that means version pinning and a deliberate upgrade process aren’t optional — they’re the whole game.
Naming and parameter conventions are external. If your organization already has an established internal module library with its own conventions, adopting AVM means either migrating consuming teams to a new interface or living with two conventions side by side during the transition. Neither is free.
Module granularity may not match your governance model. A resource module might expose parameters you’d rather lock down organization-wide, or omit a setting your compliance posture requires. You don’t get to redesign the module’s surface area — you work within it or wrap around it.
Telemetry is on by default. AVM modules include a lightweight telemetry mechanism — a deployment resource (Bicep) or provider (Terraform) that reports module usage back to Microsoft so the AVM team can track adoption. It’s opt-out, not opt-in, controlled by a parameter on each module. That’s a reasonable default for Microsoft’s purposes, but it’s exactly the kind of setting an enterprise platform team needs a standard position on — decided once, applied consistently — rather than leaving to whichever engineer happens to instantiate a given module.
Versioning discipline is now a third-party-dependency problem. Unpinned AVM module references behave like any other unpinned external dependency: fine until an upstream rename, deprecation, or default-value change ships silently into your next deployment.
Why AVM is a strong foundation for your own module library — not just a direct dependency
The instinct a lot of platform teams have is to treat this as binary: either build everything custom, or consume AVM modules directly wherever they’re referenced. The more durable pattern, especially at landing zone scale, is neither — it’s treating AVM as the baseline you build your own governed layer on top of.
A few reasons this works better than either extreme:
It skips the design phase most internal module efforts get stuck in. A huge share of the time a platform team spends building “our own module library” from scratch goes into arguing about interface conventions before a single resource gets deployed. AVM’s specification has already had that argument, in public, informed by patterns across every Azure customer using it. Starting from that baseline means your team’s design effort goes into the 20% that’s genuinely yours, not the 80% every other Azure shop has already solved.
A thin wrapper layer gives you a real internal versioning boundary. If dozens of teams reference AVM modules directly and independently, every upstream version bump becomes dozens of teams’ problem to notice and test. If your platform team wraps AVM modules once, centrally, you absorb that churn in one place and expose a stable, organization-versioned interface downstream — which is the same discipline you’d want for any critical shared dependency, and it’s far easier to enforce with one wrapper layer than with a hundred scattered direct references.
It supports a maturity model instead of forcing an all-or-nothing call. Consume AVM resource modules directly for the generic, low-risk primitives where your organization has no meaningful customization to add — storage accounts, base networking, monitoring scaffolding. Reserve your own pattern modules for the pieces that are genuinely org-specific: custom security controls, compliance patterns tied to your industry, naming and tagging enforcement that reflects your governance model. Most landing zones end up as a blend of both, and AVM as a starting point lets you decide that split deliberately instead of by accident.
Governance actually lives in the wrapper, not in the module. Standardizing your telemetry opt-out decision, enforcing mandatory diagnostic settings, injecting your organization’s tagging taxonomy, gating which module versions are approved for use — none of that needs to be reimplemented by every consuming team if it’s built once into a wrapper layer around the AVM modules you adopt.
When you do need to diverge, you’re forking from a tested baseline, not a blank page. Eventually some part of your platform will need something AVM’s generic assumptions don’t cover. At that point you’re not writing a module from zero — you’re extending or forking something that’s already WAF-aligned, already documented, already tested against real-world usage. That’s a materially better starting position than most hand-built internal modules ever reach.
A practical adoption path
- Map your existing custom modules against the current AVM catalog — a larger share than you’d expect will already have a direct resource-module equivalent, especially for generic infrastructure.
- Build the wrapper layer before you need custom logic, not after. This is where you standardize telemetry settings, tagging, diagnostics, and version-pinning policy from day one, rather than retrofitting governance onto modules already in wide use.
- Pin AVM module versions explicitly and treat upgrades as a reviewed, tested change — never an automatic pull into production landing zones.
- Reserve genuinely custom pattern modules for the org-specific pieces AVM doesn’t cover, instead of trying to force generic modules to do everything.
- Revisit the mapping periodically. AVM’s catalog is still growing, and a module you built in-house last year may have a solid upstream equivalent now.
The platform engineering takeaway
Standardizing IaC across an enterprise landing zone is a governance problem as much as a technical one. What AVM changes is where your governance effort gets spent: instead of relitigating module design and WAF alignment that every other Azure customer has already fought over, your platform team can put that effort into the genuinely org-specific 20% — while using AVM, wrapped in a governed layer, as the foundation for everything else.
Discover more from ksharp
Subscribe to get the latest posts sent to your email.