A stripped-down, opinionated, deployable Azure Landing Zone for digital-native companies and startups. Based on Microsoft's Azure Landing Zone (ALZ) — formerly Enterprise-Scale Landing Zone (ESLZ) — minus the enterprise complexity.
Built for teams of 5-50 engineers who need to get Azure right from day one without spending two months on "cloud foundations."
- One management group, two subscriptions (Prod + Non-Prod) is all you need to start. Don't over-engineer your hierarchy.
- Skip the hub network, Azure Firewall, and dedicated Connectivity subscription until you actually have hybrid/on-prem requirements or 10+ workloads.
- Enable Defender for Cloud CSPM (free) + Defender for Servers P2 on prod only. Turn on diagnostic settings to a single Log Analytics workspace. That's your security baseline.
- Set budget alerts at 50%, 80%, and 100% of your monthly burn. Tag everything with
environmentandteam. No exceptions. - Deploy this in under 1 hour with Bicep or Terraform. Graduate to full ALZ when you hit ~50 engineers, multi-region, or regulatory compliance requirements.
For a comprehensive walkthrough of the full Azure Landing Zone journey — from identity and RBAC to Platform and Application Landing Zones — see From Zero to Hero with Azure Landing Zones. This project takes that foundation and distills it into a deployable starting point for startups.
| What Exists Today | The Problem |
|---|---|
| ALZ (Enterprise Scale) | 100+ modules, months to understand, built for 10k-seat enterprises |
| ALZ-Bicep | Still enterprise-scoped, overwhelming for a 10-person startup |
| CAF Terraform Module | Enterprise-scoped, in extended support (archived Aug 2026). Microsoft recommends migrating to Azure Verified Modules. |
| This project | Deploys in 1 hour. Grows with you. Written for engineers, not consultants. |
⚠️ Important: This project is not a replacement or competitor to Azure Landing Zones (ALZ) or the Trey Research small-enterprise reference. It targets a different profile entirely: very early-stage startups (pre-seed to Series A), 5–15 engineers, no dedicated platform team, typically a single workload in a single region, and no hybrid connectivity requirements. For those teams, the alternative isn't ALZ — it's usually a single subscription with zero governance. This project provides a minimal but secure baseline to start with, and an explicit graduation guide for when they're ready to evolve into the full ALZ architecture.
Tenant Root Group
└── mg-<yourcompany> ← Baseline policies applied here
├── sub-<yourcompany>-prod ← Production workloads
└── sub-<yourcompany>-nonprod ← Dev, staging, QA
vnet-<co>-prod (10.0.0.0/16)
├── snet-aks 10.0.0.0/20
├── snet-app 10.0.16.0/22
├── snet-data 10.0.20.0/22
└── snet-shared 10.0.24.0/24
vnet-<co>-nonprod (10.1.0.0/16)
└── (same layout)
No hub. No Azure Firewall. No VNet peering. Each subscription is self-contained. Read more →
You need:
- Azure CLI — Install guide
- Terraform >= 1.5.0 — Install guide (only for Terraform option)
- Two Azure subscriptions — One for prod, one for non-prod. Create a subscription
- Permissions — Owner on both subscriptions (or Owner on the Tenant Root Group if deploying management groups)
Run the pre-flight check to verify everything:
git clone https://github.com/ricmmartins/sslz.git
cd sslz
# Login to Azure
az login
az account set --subscription <YOUR_PROD_SUBSCRIPTION_ID>
# Check all prerequisites
./scripts/validate-prerequisites.shIf the script reports errors, fix them before proceeding. See Troubleshooting for common issues.
This step creates the management group hierarchy shown in the Architecture diagram. It requires tenant-level permissions (Owner or Management Group Contributor on the Tenant Root Group). Skip this if you don't have tenant-level access — the landing zone works without it.
az deployment tenant create \
--location eastus2 \
--template-file infra/bicep/modules/management-groups.bicep \
--parameters \
companyName='<yourcompany>' \
prodSubscriptionId='<PROD_SUBSCRIPTION_ID>' \
nonprodSubscriptionId='<NONPROD_SUBSCRIPTION_ID>'cd infra/terraform/modules/management-groups
terraform init
terraform apply \
-var='subscription_id=<ANY_SUBSCRIPTION_ID>' \
-var='company_name=<yourcompany>' \
-var='prod_subscription_id=<PROD_SUBSCRIPTION_ID>' \
-var='nonprod_subscription_id=<NONPROD_SUBSCRIPTION_ID>'
cd ../../../..Note: The
subscription_idis required by the azurerm provider for authentication, even though management groups are tenant-level resources. You can use either your prod or non-prod subscription ID.
Choose one option: Bicep or Terraform.
cd infra/bicep
# Copy and edit the parameter file for your environment
cp parameters/prod.bicepparam parameters/prod.local.bicepparamOpen parameters/prod.local.bicepparam and change these values (the .local. copy keeps your settings out of version control):
companyName— Your company name (e.g.,'acme'). Used in all resource names.securityContactEmail— Email for Defender for Cloud alerts.budgetAlertEmails— List of emails for budget notifications.monthlyBudgetAmount— Your monthly budget in USD.
# Preview what will be created (no changes made)
az deployment sub what-if \
--location eastus2 \
--template-file main.bicep \
--parameters parameters/prod.local.bicepparam
# Deploy
az deployment sub create \
--location eastus2 \
--template-file main.bicep \
--parameters parameters/prod.local.bicepparamRepeat for non-prod by creating a nonprod.local.bicepparam file with environment = 'nonprod' and switching subscriptions:
az account set --subscription <YOUR_NONPROD_SUBSCRIPTION_ID>cd infra/terraform
# Copy and edit the variables file
cp terraform.tfvars.example terraform.tfvarsOpen terraform.tfvars and fill in the REQUIRED values (marked in the file):
subscription_id— Your Azure subscription UUIDcompany_name— Your company name (e.g.,"acme")environment—"prod"or"nonprod"budget_alert_emails— List of email addressessecurity_contact_email— Email for security alerts
# Initialize Terraform
terraform init
# Preview what will be created (no changes made)
terraform plan -out=tfplan
# Deploy (review the plan output carefully before confirming)
terraform apply tfplanImportant: For CI/CD and team use, set up a remote backend for Terraform state. Run
./scripts/bootstrap-backend.sh -s <storage-account-name>to create the backend storage, then configure your workflow with the storage account name. For local dev without a backend, runterraform init -backend=false. See CI/CD Setup for full instructions.
After deployment completes, verify in the Azure Portal or CLI:
# Check resource groups were created
az group list --query "[?contains(name, 'yourcompany')].name" -o tsv
# Check Log Analytics workspace
az monitor log-analytics workspace list --query "[].name" -o tsv
# Check policy assignments
az policy assignment list --query "[].displayName" -o tsv
# Check Defender plans enabled
az security pricing list --query "value[?pricingTier=='Standard'].{Name:name, Tier:pricingTier}" -o table
# Check security contact
az security contact show --name default --query "{Email:emails, Roles:notificationsByRole.roles}" -o table
# Check budget
az consumption budget list --query "[].{Name:name, Amount:amount, TimeGrain:timeGrain}" -o table
# Check NSG rules
az network nsg list --query "[].name" -o tsvSee the Day-1 Checklist below, and CI/CD Setup if you're configuring GitHub Actions.
To destroy all landing zone resources:
# Terraform
./scripts/teardown.sh --tool terraform --env nonprod --company yourcompany
# Bicep
./scripts/teardown.sh --tool bicep --env nonprod --company yourcompany- Verify Entra ID tenant is set up, custom domain added
- Enable Security Defaults (Entra ID > Properties > Security Defaults)
- Create break-glass account with hardware MFA key
- Create security group
sg-azure-admins, add 2-3 founders/leads
- Assign
sg-azure-adminsas Owner on the management group - Create Entra ID groups:
sg-azure-developers,sg-azure-readers - Assign RBAC roles (see Security docs)
- Set up CI/CD with Workload Identity Federation
- Test a sample deployment end-to-end
| Component | What You Get |
|---|---|
| Management Groups | Single MG with two subscriptions underneath |
| Azure Policy | Microsoft Cloud Security Benchmark (audit), required tags, allowed locations |
| Networking | VNet + subnets per subscription, NSGs with deny-all-inbound default |
| Monitoring | Log Analytics workspace, Activity Log forwarding, diagnostic settings policy |
| Security | Defender for Cloud CSPM, Defender for Servers P2 (prod), MFA via Security Defaults |
| Cost Management | Budget alerts at 50/80/100%, tagging enforcement |
| CI/CD | GitHub Actions workflows for Bicep and Terraform |
These are enterprise components you should add later when needed:
| Component | Add When... |
|---|---|
| Hub VNet + Azure Firewall | Hybrid connectivity or centralized egress control required |
| ExpressRoute / VPN Gateway | On-prem connectivity needed |
| Multiple MG layers | 5+ subscriptions with different policy needs |
| Private DNS Zones at scale | 3+ PaaS services using Private Endpoints across VNets |
| Advanced Conditional Access | 30+ Azure users or regulated customer data |
| PIM (Privileged Identity Management) | You need just-in-time admin access (Series B+) |
See Graduation Guide for detailed migration paths to full ALZ.
Pre-built configurations for common startup archetypes:
| Example | Description |
|---|---|
| SaaS Startup | Container Apps + Azure SQL Elastic Pool + Redis + Key Vault |
| AI Startup | AKS with GPU node pools + Azure OpenAI + Blob Storage |
| API-First Startup | App Service + API Management + Cosmos DB |
- Architecture Decisions — Why this layout, what we skipped, and when to revisit
- Resource Inventory — Complete list of every Azure resource created
- Networking Deep Dive — VNet design, NSGs, when you need a hub
- Security Baseline — Defender, RBAC, logging, network security
- Cost Management — Budgets, RI guidance, common mistakes
- CI/CD Setup — Workload Identity Federation, GitHub Actions, secrets
- Troubleshooting — Common deployment errors and fixes
- Graduation Guide — When and how to migrate to full ALZ
See CONTRIBUTING.md. We welcome PRs — especially real-world configurations from startup CTOs and platform engineers who've battle-tested this.