# New ALZ Accelerator: lessons learned

This post was written for the **Azure Spring Clean 2025** event. Visit the official [**website**](https://www.azurespringclean.com/) to see the schedule and links to great content.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1710097165513/ba98c8eb-5674-414f-8a34-9b7429da6278.png?auto=compress,format&format=webp align="center")

# Introduction

Azure Landing Zones (ALZ) have become the de facto standard for designing and implementing scalable, secure, and well-governed cloud environments. As an integral part of the Cloud Adoption Framework for Azure, the [ALZ methodology](https://aka.ms/alz) has significantly evolved over the years. Today, it is supported by a vibrant community that engages through [GitHub discussions](https://github.com/Azure/Enterprise-Scale/discussions) and [community calls](https://aka.ms/ALZ/CommunityCall).

The coding assets for ALZ have also matured and expanded to address diverse scenarios and tooling requirements. The **latest release of the ALZ Accelerator** simplifies the bootstrapping and provisioning of cloud platforms, covering everything from source control repositories and pipelines to Azure resources for platform landing zones.

In this blog post, I will share my experience implementing this new accelerator. I will compare it with the original accelerator (now referred to as “classic”), highlight the pros and cons of the design choices, and point out areas where we applied additional customizations, explaining the rationale behind these decisions.

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">This isn’t a comprehensive guide for using the ALZ Accelerator from start to finish but rather a reflection of a specific implementation I have done and its objectives, and what I have learned from it. Be aware that in some sections I am focusing on the Bicep experience, so some information will not be true or relevant for the <em>Terraform path</em>.</div>
</div>

# Core features of ALZ Accelerator

If you wanted an ‘elevator pitch’ for the new ALZ Accelerator, we could say, it:

* breaks down the entire ALZ **deployment experience into four phases**: first two - Planning and Pre-requisites - are manual ones, but the other two - Bootstrap and Run - are fully automated.
    
* uses an opiniated approach for **deploying and managing the platform landing zones** of the ALZ reference architecture. The Accelerator engineering team made a lot of design decisions to simplify the experience by **abstracting the complexity** of deploying the entire ‘ALZ stack’. *The Accelerator doesn’t deal with workload landing zones, and it doesn’t integrate directly with the Vending machine module!*
    
* supports both Bicep and Terraform for IaC modules. *Due to Terraform’s versatility with close to five thousand providers, it is used in the Bootstrap phase even if you choose Bicep as your IaC language.*
    
* creates a **continuous delivery environment** in either Azure DevOps or GitHub. *Alternatively, you could ‘bring your own VCS’ as well and use other services like GitLab, but you need to configure such integration yourself.*
    
* uses a new ALZ [PowerShell module](https://www.powershellgallery.com/packages/ALZ) that gathers user input, configures the bootstrap environment, and ensures you can deploy the platform landing zones from it.
    

Its main objective, in my view, is to accelerate, rather than to provide every conceivable design and configuration option. This is done through abstraction and end-to-end automation.

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">The ALZ core team has introduced a new home for technical documentation. The work is still ongoing, but I would encourage you to bookmark <a target="_self" rel="noopener noreferrer nofollow" href="https://aka.ms/ALZ/TechDocs" style="pointer-events: none">aka.ms/ALZ/TechDocs</a> link and start using it.</div>
</div>

# The big picture and phases

I like this diagram, breaking down the experience to components and phases:

[![Credit: Microsoft - ALZ Accelerator project - https://azure.github.io/Azure-Landing-Zones/accelerator/](https://azure.github.io/Azure-Landing-Zones/accelerator/img/alz-terraform-accelerator.png align="center")](https://azure.github.io/Azure-Landing-Zones/accelerator/#accelerator-features)

I would encourage you to go through the documentation and learn the details but here is my simplified version of the entire process:

1. Start with **planning**: most organizations have some footprint in Azure already (aka Brownfield), so you need to consider where you are going to ‘attach’ the new Management Group hierarchy (with policies and roles), what IaC language and VCS platform you want to use, etc.
    
    <div data-node-type="callout">
    <div data-node-type="callout-emoji">⚠</div>
    <div data-node-type="callout-text">I assume you are familiar with the ALZ reference architecture, its principles, design areas, and all the design decisions you should carefully make for your production environment. Without this knowledge it is quite impossible to comprehend what the ALZ Accelerator does, and what value it provides!</div>
    </div>
    
    The documentation gives many recommendations you should consider like:
    
    * using `Tenant Root Group` as the parent management group
        
    * using *Three subscription model* with separate Management, Connectivity, and Identity platform subscriptions, and deploy bootstrap resources to the Management subscription.
        
    * choosing between public or private networking for either self-hosted or Microsoft/GitHub-hosted agents (runners).
        
    
    *There is a comprehensive* [*spreadsheet*](https://azure.github.io/Azure-Landing-Zones/examples/tf/accelerator/config/checklist.xlsx) *available containing all configuration settings you could use and later fill out configuration files.*
    
    ![A screenshot showing a portion of the ALZ Accelerator checklist spreadsheet.](https://cdn.hashnode.com/res/hashnode/image/upload/v1740933414311/cabb5cdd-3790-46d9-95ff-e6425415268a.png align="center")
    
2. Validate you have all [**pre-requisites** in place](https://azure.github.io/Azure-Landing-Zones/accelerator/userguide/1_prerequisites/): from tools installed on your admin machine (PWSH, Az CLI, Git), configuration of your chosen VCS (things like PAT tokens and permissions), to having empty Azure subscriptions for platform LZs and an account with sufficient roles assigned).
    
    <div data-node-type="callout">
    <div data-node-type="callout-emoji">💡</div>
    <div data-node-type="callout-text">Tip: Once you download the ALZ module, there is a handy <code>Test-AcceleratorRequirements</code> cmdlet you could use to validate your machine.</div>
    </div>
    
3. **Bootstrap** phase: Here you install the ALZ module and based on chosen VCS and IaC combination, you follow additional guidance to create a local folder structure and prepare a bootstrap configuration file.
    
    Once ready, you can **trigger the bootstrap** by calling `Deploy-Accelerator` cmdlet with a few parameters. Behind the scenes, it calls Terraform to provision a [collection of resources](https://azure.github.io/Azure-Landing-Zones/accelerator/img/components.png) both in Azure and your chosen VCS side.
    
    To give you a concrete example, when choosing *Bicep with Azure DevOps and public networking scenario*, it creates: two user assigned managed identities with federated credentials, a project, a repository with environments, a group, pipelines for CI and CD, service connections with workload identity federation, and a variable group. There could be some additional components based on the choices you make and declare in the bootstrap configuration yaml file. There are several sample config files available to pick and modify like [this one for Azure DevOps and Bicep](https://raw.githubusercontent.com/Azure/ALZ-Bicep/refs/heads/main/accelerator/examples/bootstrap/inputs-azure-devop.yaml).
    
    *Note: This phase uses IaC module stored in the* [*Azure/accelerator-boostrap-modules*](https://github.com/Azure/accelerator-bootstrap-modules) *repository on GitHub. You can see all the code if you are curious about how it was designed and written.*
    
    <div data-node-type="callout">
    <div data-node-type="callout-emoji">ℹ</div>
    <div data-node-type="callout-text">The Bootstrap is meant to be executed once and when completed, you would leverage the CD pipeline (workflow) in your chosen VCS to deploy the platform LZs and maintain their lifecycle there.</div>
    </div>
    
4. When you check your terminal output to see that the bootstrap went well, it is time to head to your new repository. That’s where you **Run** the continuous delivery pipeline for the first time and use *Starter Modules* to deploy a specific platform landing zone configuration.
    

# Customization

There are **several ways** for customizing your ALZ environment and its configuration:

* Bootstrap configuration file (e.g., `input.yaml`) - mainly used to provide config choices for provisioning VCS components and Azure resources that support the CI/CD workflow. Some of this configuration is reused in the Starter module (and copied over to the `config/parameters.json` file).
    
* Names for bootstrap resources in Azure use a `service name` and `environment name` parameter values. If you want to use an alternative naming convention for resources, it can be overridden by following this [guidance](https://azure.github.io/Azure-Landing-Zones/accelerator/faq/).
    
* Two additional options are available, but only for Terraform:
    
    * Platform Landing Zone Configuration File (for TF ALZ Starter module)
        
    * Platform Landing Zone Library (lib) Folder. (for Platform Landing Zone Starter module)
        
* You could fork and modify the modules directly as described in this [Consumer Guide](https://github.com/Azure/ALZ-Bicep/wiki/ConsumerGuide#customizing-the-alz-bicep-modules). This will, however, be out of sync with the CD pipeline created by the Accelerator since it always pulls the entire modules package from its upstream (`Azure/ALZ-Bicep`).
    

There might be **additional areas** for changing the configuration stored in the repository once you pass the Bootstrap phase (before you run the CD pipeline for the first time), but I couldn’t find any reference to it in the documentation:

* Modify the `/config/parameters.json` file and add module variables to further customize the environment.
    
* Modify the parameter files (in JSON format) in the `config/custom-parameters` folder. *By inspecting the workflow definition files it does seem they are used for every CD run, but the documentation doesn’t mention it (or at least I couldn’t find it).*
    

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1740947483208/8ef07b48-8940-48a3-ad24-74760317b306.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">⏲</div>
<div data-node-type="callout-text">I will update this blog post later if I find more information about these additional customization options or test them in my sandbox environment.</div>
</div>

# Code repositories in the ALZ universe

I always like to build a mental map of different ‘building blocks’ / code sources and how they relate to one another. The diagram I made focuses on the *Bicep path of the Accelerator* (with some components being common for the *Terraform path*):

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1740941073366/9d163877-dda5-4bda-97ef-3371bc03efe0.png align="center")

* Your journey with the ALZ Accelerator should begin with the *new* documentation page - **Azure Landing Zones Documentation**. It is available using the handy [aka.ms/alz/accelerator](https://aka.ms/alz/accelerator) shortcut and it is sourced from the `Azure\Azure-Landing-Zones` repository.
    
* You will download and install the **ALZ module** from the [PowerShell Gallery](https://www.powershellgallery.com/packages/ALZ/). The source for the code is in the `Azure\ALZ-PowerShell-Module` repository.
    
* During the Bootstrap phase, the automation is leveraging the **Bootstrap modules** hosted in the `Azure/accelerator-bootstrap-modules` repository. It uses Terraform due to its ability to provision resources in Azure, Azure DevOps, and GitHub, but it doesn’t limit your options for selecting Bicep as your IaC language for the Run phase.
    
* When you trigger the **continuous delivery pipeline** (workflow) in your VCS repository or a project, as part of the flow it downloads the latest release (zip) of ALZ-Bicep modules package (f*or Terraform, it is a different source repository*). That one is maintained in the `Azure/ALZ-Bicep` repo.
    
    * When you inspect that repository and its code, you will see that all Bicep modules (except one: `ptn/network/private-link-private-dns-zones`) are stored locally.
        
    * Being able to use and reference these modules directly from the Microsoft Public Bicep Registry through the [Azure Verified Modules](https://aka.ms/AVM) initiative is on the roadmap, which is why there isn’t a “link” between the ALZ-Bicep repo and the AVM repository for Bicep - `Azure/bicep-registry-modules` - in my diagram.
        
    * You can even spot traces of AMV’s predecessor CARML (in the `CRML` folder).
        
* I understood from one ALZ external community call that when it comes to custom policy definitions for ALZ, the upstream repository is still the original `Azure/Enterprise-Scale` and there is a workflow making sure the downstream ALZ-Bicep is updated on a regular basis. *This might not be entirely correct!*
    
* As I mentioned above, the Bicep module for Subscription Vending - `Azure/bicep-lz-vending` - is not directly integrated with the Accelerator.
    

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">I hope this breakdown helped you to ‘connect the dots’ and better understand how the entire code base for ALZ is distributed and intertwined, but you can certainly use the ALZ Accelerator without it 😀.</div>
</div>

# New vs. Classic Accelerator

For those of you who tried the earlier versions of the ALZ Bicep Accelerator, you might have seen this [disclaimer](https://github.com/Azure/ALZ-Bicep/wiki/ClassicAccelerator) in the ALZ Bicep Wiki:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1740948406016/fc039ceb-e5e6-41c5-84d9-383896f1cfef.png align="center")

The **Classic Accelerator** used a collection of workflows and respective PowerShell scripts to manage parts of the Platform Landing Zone.

The **new ALZ Accelerator** uses only two pipelines (workflows): CI and CD. It also leverages reusable workflows (or pipeline templates).

Also, all parts of the platform are treated as steps and the provisioning is sequenced inside one job, as shown in the screenshot below from one of my test deployments with Azure DevOps and Bicep combo:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1740949485060/b48f8692-34ef-49ab-b752-e94cf6067f3b.png align="center")

# My implementation

I planned to deploy the ALZ reference architecture in our internal tenant (in a Brownfield fashion) and at the same time assess the new Accelerator and its new features. It seemed to be a great fit, especially since I wanted to use IaC and the *gitops style* of managing the landing zones.

For the Bootstrap phase, I selected:

* Bicep as `iac_type`
    
* alz-github as `bootstrap_module_name`
    
* Complete `starter_module_name`
    
* `Tenant Root Group` as the Parent MG
    
* I went with the ‘Three subscriptions model’ and deployed the boostrap resources in the Management subscription
    
* I didn’t see compelling reasons for using private networking and self-hosted runners. *This would have been different if I chose Terraform as IaC, even though there are two ways for keeping the state file in a secured blob storage - Large Runners or Azure VNet integration*.
    

## What didn’t work for us

![](https://media.makeameme.org/created/houston-we-have-5acf5f.jpg align="center")

While I was studying the composition of this solution and its customization options, I quickly realized that I would need to deviate from my desired “layout” and that several of my **key requirements** **are not compatible with the new Accelerator and its design**:

* Store the configuration of each platform landing zone in a separate code repository:
    
    * I want to delegate access to different platform LZs to separate teams. The Accelerator uses the ‘monorepo’ approach for storing configuration, so delegating the responsibility for parts of the configuration to different teams would be cumbersome, especially since it uses one primary configuration file (`config/parameters.json`).
        
    * Such distribution to several repos and respective workflows could simplify and speed up redeployments and configuration changes.
        
* Be true to the code-first infrastructure provisioning principle and treat the code repository as a single source of truth:
    
    * The Accelerator doesn’t honor this principle, since it provisions the bootstrap resources (managed identities, ACR, etc.) in ‘fire and forget’ fashion. I know this is a classic ‘chicken and egg’ problem, but it would be great to be able to ‘import’ those resources to the Management LZ repo.
        
* I prefer having a more direct access to IaC deployment files and its parameters over such high level of abstraction:
    
    * I wanted to be able to add additional components to platform LZs that are either not part of the reference implementation (e.g., replica domain controllers, Azure VNet Manager) or aren’t implemented in a flexible enough way (e.g., Azure Firewall policies).
        

## Path we are (probably) taking

At the time of writing this blog post, we haven’t completely decided what implementation approach we are going to choose but considering the requirements I described above, we will most likely:

* avoid using the ALZ Accelerator due to the abovementioned reasons
    
* create four GitHub repositories (not counting the existing repo for reusable workflows we already have in the organization) and map them to three Platform subscriptions:
    
    ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1740951765252/f2b3edf0-820f-4638-8f19-5a73137fdb98.png align="center")
    
* fork the ALZ Bicep modules from the `Azure/ALZ-Bicep` repo to a *Private Modules Library* and publish them in our Private Bicep Registry.
    
    <div data-node-type="callout">
    <div data-node-type="callout-emoji">💡</div>
    <div data-node-type="callout-text">I wrote an article about building such a library, you can find it <a target="_self" rel="noopener noreferrer nofollow" href="https://azurescholar.cloud/azure-verified-modules-and-private-modules-a-powerful-combo" style="pointer-events: none">here</a>.</div>
    </div>
    
* follow the [Module Deployment Sequencing guidance](https://github.com/Azure/ALZ-Bicep/wiki/DeploymentFlow#module-deployment-sequence) but split it in a way to match it with the repos-subs mapping
    

Obviously, this requires a lot of additional engineering work, but this approach could give us the needed level of flexibility and align with the overall [Azure Landing Zone Journey](https://azure.github.io/Azure-Landing-Zones/#the-azure-landing-zones-journey). Once the *Project Uplift* is complete and ALZ-Bicep modules are converted to AVM modules, we could easily switch the reference to `br/public` in our deployment templates.

# Conclusion

The new ALZ Accelerator is a very robust and interesting attempt to automate the deployment and lifecycle management of platform landing zones beyond what was possible previously with the original accelerators (the Portal experience, JSON ARM, Terraform, and Bicep).

The level of abstraction and the way it pulls the entire package of ALZ modules might not be a good fit for every customer, but it has clear benefits over a more complex *DYI approach*.

My wish is it eventually switches to a model, that it leverages AVMs both for Terraform and Bicep. The good news is it is on the roadmap already and there is an [open issue](https://github.com/Azure/ALZ-Bicep/issues/791) in the `Azure/ALZ-Bicep` repo:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1740946404384/2b96f9af-b3a2-48ae-85ce-508bc6335357.png align="center")

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">TIP: If you are wondering about the ALZ roadmap, you can follow it up at <a target="_self" rel="noopener noreferrer nofollow" href="https://aka.ms/alz/roadmap" style="pointer-events: none">aka.ms/alz/roadmap</a> (GitHub Project).</div>
</div>
