This project contains a custom Azure platform landing zone (PLZ), inspired by enterprise-scale architecture and based on CAF guidelines. Designed to be light-weight and cost-efficient, utilizing free or minimum pricing SKU options where possible. Ideal for a small organization, personal tenant, light production or development/training purposes.
- Infrastructure as Code (IaC) + CI/CD
- Git-driven workflow, with a merge or commit to the
mainbranch triggering automation pipelines. - Desired state of environment declared in code, using Terraform to define Azure resources and components.
- Secrets and variables stored in GitHub repository, referenced and passed during workflow run-time.
- Git-driven workflow, with a merge or commit to the
- State Segmentation
- Utilizes a dedicated IaC subscription, containing state files remotely in Azure Blob storage.
- Separate state files per deployment stack, reducing blast radius in event of data corruption or loss.
- Automated Powershell Bootstrapping
- Locally executed Powershell script automates initial setup process.
- Prepares both Azure tenant and GitHub repository for automated deployments using Terraform.
This customized design is based on classic Enterprise Scale landing zone architecture. Utilizing hub-spoke networking, centralized log collection and policy-driven governance.
Automates the initial bootstrapping process, preparing both Azure and GitHub for platform landing zone deployments.
- Locally executed Powershell script:
- Performs the initial setup process, configuring Azure and GitHub for automation.
- Performs pre-flight checks, validates authentication and confirms intentions.
- Executes pre-defined Terraform module to deploy base resources.
- Adds stack variables and secrets into the provided GitHub repository and environments.
- Automates the post-deployment migration process of local state file to Azure blob storage providing remote state.
- Service Principal + OIDC:
- Providing a secure authentication method for workflows within GitHub repository.
- Custom RBAC role assigned providing required permissions for resource management.
- Backend Resources --> Dedicated IaC Subscription:
- Resource Group and Storage Accounts per category (platform, workloads).
- Maintaining isolation and independence, using separate state files per stack (governance, connectivity, management).
Deploys and configures the core shared operational services required to run and monitor the Azure Platform Landing Zone. This stack provides centralized logging, monitoring and alerting for all platform subscriptions.
- Centralized Logging:
- Log Analytics workspace for monitoring and observability of platform resources.
- Activity, audit and metric logs sent to Log Analytics Workspace for review and retention.
- Storage Account for long term log archiving.
- Alerting & Action Groups:
- Activity, Service and Health alerting, with severity-based notifications.
- High-risk operations (resource group deletion, RBAC changes, policy modifications) are monitored using Azure Activity Log Alerts.
- Entra ID Administrative Groups:
- Create baseline administrative groups in Entra ID.
- RBAC assignments to top-level (core) management group.
- Microsoft Defender for Cloud:
- Foundational CSPM automatically enabled, free of charge, offering basic security posture management.
- Optional deployment of Cloud Security Posture Management (CSPM).
The Governance stack provides structure and policy enforcement, combining Management Groups with Azure Policy assignments. This stack lays the ground work for policy assignments and remediation to enforce resource configuration.
- Management Groups:
- Deploy multi-level Management Group structure, as defined within the
plz-governance.tfvarsfile. - Management Groups are assigned to a "Level", determining the layer of depth at which each Management Group sits (parent/child).
- Automated mapping of subscriptions to parent management groups using a subscription ID identifier value.
- Deploy multi-level Management Group structure, as defined within the
- Azure Policy:
- Custom policy definitions and initiatives, defined in JSON files and created using Terraform.
- Policy Initiative Assignments are mapped to Management Groups using the
policy_assignmentsfield in the local variables file. - Built-in Policy Initiatives are resolved by ID and assigned to target Management Groups in the
policy_initiatives_builtinvariable. - Remediation tasks enforce policy compliance continuously, ensuring current and future resources are in compliance.
Example: Management Group Structure
TENANT_ROOT
└── mg-abc-core (Core Management Group)
├── mg-abc-platform (L1: Platform subscriptions)
├── mg-abc-workload (L1: Workload subscriptions)
├── mg-abc-online (L2: Online/Internet-facing workload subscriptions)
└── mg-abc-corporate (L2: Internal/business workload subscriptions)
├── mg-abc-sandbox (L1: Dev/test/sandbox subscriptions)
└── mg-abc-decom (L1: Holding group for decommissioned subscriptions)
management_groups_level1 = {
"platform" = {
display_name = "Platform" # Contains all platform subscriptions.
parent_mg_name = "core" # Key ID of the parent Management Group.
subscription_identifiers = ["platform-dev-sub", "platform-iac-sub"] # List of subscription identifiers, first 3 segments used to resolve full ID.
}
"workload" = {
display_name = "Workload"
parent_mg_name = "core"
subscription_identifiers = ["app-myapp01-sub"]
}
}The Connectivity stack deploys the resources required for secure networking between workloads and on-prem.
- Hub-Spoke Architecture:
- Deploys a hub-spoke network architecture for centralized network management and secure traffic flow.
- Spoke VNets (workloads) peer to the central hub VNet (platform).
- Network Security Groups (NSGs) enforce rule-based traffic controls at the subnet levels.
- Azure Firewall:
- Provides centralized network security and traffic inspection for hub and spoke workloads.
- Management subnet, NIC and public IP, allowing for separation between data and operational traffic.
- Azure Bastion:
- Secure and centralized RDP and SSH connectivity to cloud VMs.
- Reduce risk by removing the need to expose public IP or endpoints for VM workloads.
- VPN Gateway:
- Site-to-Site VPN for hybrid connectivity between Azure and on-prem.
- Dedicated subnet providing gateway services for hub virtual network.
- NOTE: Requires manual input of pre-shared key for on-prem VPN service.
- Route Tables:
- When firewall is enabled, a route table forces all traffic through the firewall private IP.
- When firewall is disabled the route table is still created but with no forced routes.
- This allows associations to exist and can be populated later without state changes.
Note
Spoke VNet peering is intentionally left out of the connectivity stack, as it belongs in workload vending.
- GitHub account with a existing repository for the Azure platform landing zone project.
- Roles: Read/Write access to
actions,actions variables,administration,code,environments, andsecrets.
- Roles: Read/Write access to
- Existing Azure tenant with required roles assigned to a dedicated IaC subscription (can also be used with a single platform subscription).
- Built-in Roles: Bootstrap process requires:
Global Administrator(preferred): Required to approve MSGraph application API permissions assigned to the Service Principal.Contributor: Required to deploy initial resources.User Access Administrator: Required to assign RBAC roles.
- Built-in Roles: Bootstrap process requires:
- Applications installed locally (during bootstrap process):
- Terraform:
- Cloud-agnostic Infra-as-Code tool for deploying and managing resources in Azure and GitHub.
- Flexible with a wide range of publicly available modules and providers.
- Azure CLI:
- CLI tool required by Terraform provider (
AzureRM) to interact with Azure API.
- CLI tool required by Terraform provider (
- GitHub CLI:
- CLI tool used to interact with GitHub, connected and authenticated to the target GitHub organisation.
- Providing code repository and CI/CD workflows (GitHub Actions) for automating deployment of stacks.
- PowerShell:
- Used to execute the bootstrap automation script locally.
- High readability with extensive user base, cross platform.
- Terraform:
Stacks are deployed using GitHub Actions workflows located in .github/workflows.
Workflows are designed to be run in the order provided below for the initial deployment only.
Once the full stack list has been deployed, changes can be made, with individual workflows executed as required.
Note
Workflows are configured to execute PLAN only deployments on commit or PR. Modification is required to enable full CI/CD.
- Update variable files in
./variableswith desired inputs for each stack. - Add subscription identifier values to the
deployment_stacksvariable for stack referenced. - Bootstrap: Execute bootstrap script to begin initial configuration process.
- Management: Deploy monitoring and observability resources.
- Governance: Deploy management group structure, policy definitions and initiatives.
- Connectivity: Deploy networking resources using a hub-spoke architecture.
This project uses a semi-opinionated naming format for resources to ensure consistency, readability, and CAF alignment. Resource names are provided using a custom naming module that produces multiple naming outputs.
Template: <resource_type>-<prefix>-<workload>-<stack_or_env>-<category>-<instance>
| Segment | Purpose / Description |
|---|---|
resource_type |
Azure resource type abbreviation: rg, vnet, snet, app, sql, api, etc. |
prefix |
Tenant or project identifier, abc (Animal Balloon Company) |
workload |
plz for platform, workload name for apps/services (mywebapp) |
stack_or_env |
Platform stack (gov, con, mgt, idn) or environment (dev, tst, stg, prd) |
category |
Optional category grouping: hub, fwl, bas (used mainly for PLZ resources, optional for workloads) |
instance |
Numeric identifier: 01, 02, 03 (for multiple similar resources) |
| Resource | Name Example |
|---|---|
| Resource Group | rg-abc-plz-con-01 |
| Azure Firewall | afw-abc-plz-con-01 |
| Hub VNet | vnet-abc-plz-con-hub |
| Firewall Subnet | snet-abc-plz-con-afw |
| Web App | app-abc-mywebapp-prd-01 |
| SQL Database | sql-abc-mywebapp-prd-01 |
| Virtual Machine | vm-abc-mywebapp-prd-01 |
The following resources are created and managed automatically by Azure platform services, and are intentionally excluded from Terraform management:
| Resource | Prefix | Created by | Reason |
|---|---|---|---|
| Data Collection Endpoint | NWTA |
NetworkTrafficAnalyticsService | Defender for Cloud network traffic collection. |
| Data Collection Rule | NWTA |
NetworkTrafficAnalyticsService | Defender for Cloud network traffic collection. |
Issues are recorded and held within the issues directory as individual files.
When the issue is accepted, mitigated or resolved, the file is moved to the resolved directory.
See the Issues Register for details on active and resolved issues.
A list of references, material, and content that contributed to, or influenced this project.

