Azure Citadel
  • Blogs

  • Azure Arc
    • Overview
    • Azure Arc-enabled Kubernetes
      • Prereqs
      • Background
      • Deploy Cluster
      • Connect to Arc
      • Enable GitOps
      • Deploy Application
      • Enable Azure AD
      • Enforce Policy
      • Enable Monitoring
      • Enable Azure Defender
      • Enable Data Services
      • Enable Application Delivery
    • Azure Arc-enabled Servers
      • Prereqs
      • Scenario
      • Hack Overview
      • Azure Landing Zone
      • Arc Pilot resource group
      • Azure Monitoring Agent
      • Additional policy assignments
      • Access your on prem VMs
      • Create onboarding scripts
      • Onboarding using scripts
      • Inventory
      • Monitoring
      • SSH
      • Windows Admin Center
      • Governance
      • Custom Script Extension
      • Key Vault Extension
      • Managed Identity
    • Useful Links
  • Azure CLI
    • Install
    • Get started
    • JMESPATH queries
    • Integrate with Bash
  • Azure Landing Zones
    • ALZ Accelerator
      • Prereqs
      • Elevate
      • Bootstrap
      • Demote
      • Components
    • Deploy an Azure Landing Zone
      • Create an initial ALZ config
      • Run through the CI/CD workflow
    • Example Library Configs
      • Azure Landing Zone library
      • Azure Landing Zone library with overrides
  • Azure Lighthouse
    • Minimal Lighthouse definition
    • Using service principals
    • Privileged Identity Management
  • Azure Policy
    • Azure Policy Basics
      • Policy Basics in the Azure Portal
      • Creating Policy via the CLI
      • Deploy If Not Exists
      • Management Groups and Initiatives
    • Creating Custom Policies
      • Customer scenario
      • Policy Aliases
      • Determine the logic
      • Create the custom policy
      • Define, assign and test
  • Marketplace
    • Introduction
      • Terminology
      • Offer Types
    • Partner Center
    • Offer Type
    • Publish a VM Offer HOL
      • Getting Started
      • Create VM Image
      • Test VM Image
      • VM Offer with SIG
      • VM Offer with SAS
      • Publish Offer
      • Other VM Resources
    • Publish a Solution Template HOL
      • Getting Started
      • Create ARM Template
      • Validate ARM Template
      • Create UI Definition
      • Package Assets
      • Publish Offer
    • Publish a Managed App HOL
      • Getting Started
      • Create ARM Template
      • Validate ARM Template
      • Create UI Definition
      • Package Assets
      • Publish Offer
    • Managed Apps with AKS HOL
    • Other Managed App Resources
    • SaaS Offer HOLs
    • SaaS Offer Video Series
      • Video 1 - SaaS Offer Overview
      • Video 2 - Purchasing a SaaS Offer
      • Video 3 - Purchasing a Private SaaS Plan
      • Video 4 - Publishing a SaaS Offer
      • Video 5 - Publishing a Private SaaS Plan
      • Video 6 - SaaS Offer Technical Overview
      • Video 7 - Azure AD Application Registrations
      • Video 8 - Using the SaaS Offer REST Fulfillment API
      • Video 9 - The SaaS Client Library for .NET
      • Video 10 - Building a Simple SaaS Landing Page in .NET
      • Video 11 - Building a Simple SaaS Publisher Portal in .NET
      • Video 12 - SaaS Webhook Overview
      • Video 13 - Implementing a Simple SaaS Webhook in .NET
      • Video 14 - Securing a Simple SaaS Webhook in .NET
      • Video 15 - SaaS Metered Billing Overview
      • Video 16 - The SaaS Metered Billing API with REST
  • Microsoft Fabric
    • Theory
    • Prereqs
    • Fabric Capacity
    • Set up a Remote State
    • Create a repo from a GitHub template
    • Configure an app reg for development
    • Initial Terraform workflow
    • Expanding your config
    • Configure a workload identity
    • GitHub Actions for Microsoft Fabric
    • GitLab pipeline for Microsoft Fabric
  • Packer & Ansible
    • Packer
    • Ansible
    • Dynamic Inventories
    • Playbooks & Roles
    • Custom Roles
    • Shared Image Gallery
  • Partner Admin Link
    • Understanding PAL
    • User IDs & PAL
    • Service principals & PAL
    • CI/CD pipelines & PAL
    • Creating a dedicated PAL service principal
    • Azure Lighthouse & PAL
    • PAL FAQ
  • REST API
    • REST API theory
    • Using az rest
  • Setup
  • Sovereign Landing Zones
    • ALZ Accelerator
      • Prereqs
      • Elevate
      • Bootstrap
      • Demote
      • Components
    • Deploy Sovereign Landing Zone
      • Create an initial SLZ config
      • Run through the CI/CD workflow
      • Sovereign Landing Zone
    • Example Library Configs
      • Sovereign Landing Zone
      • Sovereign Landing Zone library with overrides
  • Terraform
    • Fundamentals
      • Initialise
      • Format
      • Validate
      • Plan
      • Apply
      • Adding resources
      • Locals and outputs
      • Managing state
      • Importing resources
      • Destroy
    • Get set up for Terraform
      • Cloud Shell
      • macOS
      • Windows with PowerShell
      • Windows with Ubuntu in WSL2
    • Using AzAPI
      • Using the REST API
      • azapi_resource
      • Removing azapi_resource
      • azapi_update_resource
      • Data sources and outputs
      • Removing azapi_update_resource
  • Virtual Machines
    • Azure Bastion with native tools & AAD
    • Managed Identities

  • About
  • Archive
  1. Home
  2. Azure Landing Zones
  3. ALZ Accelerator
  4. Components
Components
Components
ALZ Accelerator
Prereqs
Elevate
Bootstrap
Demote
Components
  • Testing the workflows

Components

A brief explanation for the various resources created by the ALZ Accelerator.

Table of Contents

  • Testing the workflows

Overview

The Azure Landing Zone Accelerator deploys a comprehensive set of components to support your landing zone implementation. These components work together to provide a complete DevOps environment for managing your Azure infrastructure.

Azure Landing Zone Accelerator components overview

Azure

Let’s start by checking on what has been created in your management subscription. You should have four new resource groups with a rg-alz-mgmt-<desc>-<region>-001 naming convention.

  • rg-alz-mgmt-agents-uksouth-001
  • rg-alz-mgmt-identity-uksouth-001
  • rg-alz-mgmt-network-uksouth-001
  • rg-alz-mgmt-state-uksouth-001

Managed Identities

The accelerator configures the identity and authentication mechanisms required for secure access to Azure resources. This includes setting up service principals and federated credentials for workload identity federation between GitHub Actions and Azure.

By default the managed identities will be in the management subscription’s rg-alz-mgmt-identity-<uksouth>-001 resource group. There are two identities for the two workflows.

  • id-alz-mgmt-uksouth-plan-001
  • id-alz-mgmt-uksouth-apply-001

Plan

The plan identity is used for all plan steps. Here you can see the permissions.

Role assignments for the managed identity used for the plan workflow

Note that the ID only has write access to a single container within the storage account used for Terraform remote state. All other permissions are a variant of reader, including the custom role, Azure Landing Zones Management Group Reader.

From the GitHub perspective, the workflows will use OpenID Connect for secret free authentication from the GitHub identity provider (IdP) to the Azure identity provider. The relationship is defined in the federated credential below, but is only valid in the context defined in the subject.

Federated workload credential for the managed identity used for the plan workflow

Anyone with write permissions on the repo can contribute a branch - as long as the branch is not main - and that will trigger the plan workflow to confirm that all of the checks are met successfully, but the identity is incapable of create, update, or destroy actions.

If a pull request is created then the main deployment workflow also uses the identity - in combination with the plan environment in GitHub - for the plan step, at which point it pauses, waiting for manual approval before moving to the apply step.

Apply

As expected, the second identity is linked to the apply step and associated GitHub environment. The apply managed identity has high levels of privilege, as seen below.

Role assignments for the managed identity used for the apply workflow

ℹ️ The managed identity will also receive additional role assignments when we deploy Azure Landing Zones, such as Owner on the management groups that will be created. Also note the use of custom roles.

Let’s examine the federated credential a little more closely as this managed identity has such elevated privileges.

OpenID Connect federated credential for the managed identity used for the apply workflow The following values in the credential must match to validate the connection:

  • Organization: richeney-org
  • Repo: alz-mgmt
  • Environment: alz-mgmt-apply
  • Branch: main
  • Workflow: richeney-org/alz-mgmt-templates/.github/workflows/cd-template.yaml

⚠️ Note that whilst the calling repo must be alz-mgmt, the workflow is in a different repo, alz-mgmt-templates. We’ll see this later.

This detail is useful to remember when we check on how GitHub is configured.

Custom roles

The accelerator defines four custom roles at the tenant root group.

Custom role definitions used by the managed identities

You can view the custom roles to see the table of permissions, the underlying JSON, and where they’re assigned. These roles have been specifically created to move away from roles such as Owner and define roles aligned with least privilege.

Remote State

Terraform state management is configured with a dedicated Azure Storage Account. This provides a secure, centralized location for storing your infrastructure state files, complete with remote state locking capability.

The storage account can be found in rg-alz-mgmt-state-uksouth-001 and is configured with private endpoint, TLS 1.2, HTTPS only, and RBAC authentication only. This removes the ability to authenticate using storage keys which is considered a potential security risk.

Private Runners

Self-hosted GitHub runners can be deployed to provide greater control over your CI/CD pipeline execution environment. These runners can be configured to run on Azure infrastructure with specific networking and security requirements.

The private runners are hosted on a couple of Azure Container Instances, with virtual network integration and ACR Pull RBAC role assignment for the system. They can be found in the rg-alz-mgmt-agents-uksouth-001 and rg-alz-mgmt-network-uksouth-001 resource groups.

Azure resources for the private runners

GitHub

OK, let’s switch focus from the Azure resources to the GitHub configuration and see how the two tie together securely.

Repos

The Azure Landing Zone accelerator has created two repositories in your organization. See the example below.

The two repositories, alz-mgmt and alz-mgmt-templates, created by the accelerator

The main repo that you will be updating in these labs is the alz-mgmt repo.

When we look at the workflows you will see that these are backed off to the alz-mgmt-templates. This provides an extra level of security protection as the federated credential for the apply step could be open to abuse if a change to the alz-mgmt’s workflows was camouflaged to reviewers in a large pull request. Separating the workflow logic into an even more secure and static repository if a good practice.

Branch protection rules

The main branch on the alz-mgmt repo also has strong branch protection rules.

Branch protection on the main branch of the alz-mgmt repo

This forces all changes to be made on branches with no direct commits to the main branch. Pull requests must be reviewed before merges are allowed, and it also forces a clean and linear history with fully resolved PR review conversations.

Envs

GitHub environments are created here to align with the plan and apply deployment stages. Here they are used to safely generate plans with the continuous integration (CI) workflow and the plan step within the continuous deployment (CD) workflow using the mostly harmless plan identity.

Environments configuration

As we saw earlier, the federated credentials for the managed identities specify the environment entity, and are linked 1:1 with the GitHub environments.

The CD workflow will not progress to the apply step - which uses the apply environment and its far more powerful managed identity - without a review of the plan.

Environment rules are configured to require manual approvals before deployments can proceed. This ensures that changes to critical environments go through a structured review process.

Environment rules for the apply environment

You will also see the variables for the managed identity’s client IDs are also defined at the environment level.

Variables

The Azure Landing Zones accelerator automatically configures both repository-level and environment-specific variables as used by the workflows.

Environment and repo level variables used in the GitHub Actions workflows

Again, you can see the AZURE_CLIENT_ID is defined at the environment level so that it will always resolve to the client id for the respective managed identity.

GitHub Actions

The two workflows in the main repo can be found in alz-mgmt’s .github/workflows folder. Both may also be triggered manually with the workload_dispatch trigger, but we’ll concentrate on the CI/CD flow.

Continuous Integration

The ci.yaml workflow is triggered on pull requests to the main branch. The workflow applies two jobs as checks in the pull request flow.

  1. Validate Terraform ensures it passes the standard fmt, init, and validate commands on the config.
  2. Validate Terraform Plan checks that the plan can be successfully generated and then adds it directly into the pull request.

The CI workflow allows a contributor to confirm that their config is in a healthy state and correct any issues before a review occurs. The included plan make it simple for standard reviews and resolution to happen within the pull request flow. All jobs are run within the alz-mgmt-plan environment.

Continuous Deployment

The cd.yaml workflow is triggered upon push into main, when a pull request is approved and merged.

  1. Plan with Terraform has steps to create, upload and display the plan file artifact, and is run in the alz-mgmt-plan environment.
  2. Apply with Terraform uses the alz-mgmt-apply environment, triggering the required manual approval via the environment rules. The approver must be one of the members of the alz-mgmt-approver team that the accelerator defined at the organization level. Once approved the job applies the configuration to the environment using the apply managed identity.

Workflow templates

The other key aspect of both workflows is that they are themselves small and lightweight and use the corresponding workflows in the alz-mgmt-templates repo.

This is where you will find the underlying steps and logic for the GitHub Actions workflows.

Self Hosted Runners

Runner groups allow you to organize your self-hosted runners and control which repositories can use them.

Private runners in GitHub Actions

The two ACI container groups in Azure map directly to the self-hosted runners that you can see defined in GitHub Actions.

Testing the workflows

You can now run the two GitHub Actions workflows. They should complete successfully without deploying anything as we have an empty config file.

We are now set up to use the ALZ module examples to build up and deploy a configuration.

Source: https://icy-island-077f0c303-135.westeurope.4.azurestaticapps.net/alz/accelerator/components/
Published: 10 Oct 2025
Printed:
Demote Components Next