| layout | home |
|---|---|
| title | Startup-Scale Landing Zone (SSLZ) |
| description | A stripped-down, opinionated, deployable Azure Landing Zone for startups. Deploy in under 1 hour. |
A stripped-down, opinionated, production-ready Azure Landing Zone designed for startups and digital-native teams. Built for companies with 5–50 engineers that need to get Azure right from day one without enterprise complexity.
environment and team. No exceptions.Enterprise-grade foundations without enterprise complexity.
From zero to production-ready Azure with Bicep or Terraform. No consultants required.
Defender for Cloud, RBAC, NSG deny-all defaults, policy enforcement from day one.
100+ modules, months to understand, built for 10k-seat enterprises
Still enterprise-scoped, overwhelming for a 10-person startup
Enterprise-scoped, in extended support (archived Aug 2026). Microsoft recommends migrating to Azure Verified Modules.
Simple, self-contained subscriptions. No hub network, no Azure Firewall — until you need them.
From zero to production-ready in under an hour.
Clone the repo, log in to Azure, and validate your environment. You'll need Azure CLI, two subscriptions (prod + nonprod), and Owner permissions.
Create the management group hierarchy. Requires tenant-level permissions (Owner on Tenant Root Group). Skip if you don't have access — the landing zone works without it.
Bicep command
az deployment tenant create \
--location eastus2 \
--template-file infra/bicep/modules/management-groups.bicep \
--parameters \
companyName='<yourcompany>' \
prodSubscriptionId='<PROD_SUB_ID>' \
nonprodSubscriptionId='<NONPROD_SUB_ID>' </details>
<details>
<summary>Terraform command</summary>
cd infra/terraform/modules/management-groups
terraform init
terraform apply \
-var='subscription_id=<ANY_SUB_ID>' \
-var='company_name=<yourcompany>' \
-var='prod_subscription_id=<PROD_SUB_ID>' \
-var='nonprod_subscription_id=<NONPROD_SUB_ID>'
cd ../../../.. </details>
</div>
<div class="step-card">
<div class="step-number">3</div>
<h3>Deploy</h3>
<span class="step-time">20 min</span>
<p>Deploy the landing zone — policies, networking, monitoring, Defender for Cloud, and budgets. Copy the parameter file, edit with your values, preview with what-if/plan, then deploy.</p>
<details>
<summary>Bicep commands</summary>
cd infra/bicep
# Copy and edit parameters (companyName, emails, budget, etc.)
cp parameters/prod.bicepparam parameters/prod.local.bicepparam
# Preview changes (no resources created)
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.bicepparam \
--name "lz-prod-$(date +%Y%m%d-%H%M%S)" </details>
<details>
<summary>Terraform commands</summary>
cd infra/terraform
# Copy and edit variables (subscription_id, company_name, emails, etc.)
cp terraform.tfvars.example terraform.tfvars
# For local dev (no remote backend):
terraform init -backend=false
# For CI/CD or team use, set up remote backend first:
# ./scripts/bootstrap-backend.sh -s <storage-account-name>
# terraform init -backend-config="storage_account_name=<name>"
terraform plan -out=tfplan # Preview changes
terraform apply tfplan # Deploy </details>
</div>
<div class="step-card">
<div class="step-number">4</div>
<h3>Verify</h3>
<span class="step-time">5 min</span>
<p>Confirm resource groups, Log Analytics, policies, and Defender plans were created correctly.</p>
<details>
<summary>Show commands</summary>
# Check resource groups
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
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 tsv </details>
</div>
<div class="step-card">
<div class="step-number">5</div>
<h3>Post-Deploy</h3>
<span class="step-time">30 min</span>
<p>Assign RBAC roles to your team, set up CI/CD with Workload Identity Federation, and enable cost anomaly alerts. See the <a href="#day-1-checklist">Day-1 Checklist</a> below.</p>
<details>
<summary>Teardown commands (if needed)</summary>
# Remove all landing zone resources
./scripts/teardown.sh --tool terraform --env nonprod --company yourcompany
./scripts/teardown.sh --tool bicep --env nonprod --company yourcompany </details>
</div>
90 minutes from zero to production-ready. Three phases, one afternoon.
- 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
- Run Bicep or Terraform deployment — see Step 3 above
- Verify resources in Azure Portal
- 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
Enterprise components you should add later when needed.
Pre-built configurations for common startup archetypes.
Practical guides written for engineers, not consultants.
Why this layout, what we skipped, and when to revisit
Complete list of every Azure resource created
VNet design, NSGs, and when you actually need a hub
Defender, RBAC, logging, and network security
Budgets, reservations, and common cost mistakes
Workload Identity Federation and GitHub Actions
Common deployment errors and fixes
When and how to migrate to full ALZ
Visual diagrams of the full landing zone