-
Notifications
You must be signed in to change notification settings - Fork 95
End to End Deployment Walkthrough
This walkthrough is the long-form operating path for deploying the Azure Landing Zone Lab safely. It assumes the reader is a cloud engineer who wants to validate the complete environment without exposing management ports or leaving expensive resources running.
Use this page with:
- Quick Start
- Deployment Profiles
- Remote State and Secrets
- Terraform Plan Review Guide
- Azure Portal Validation Evidence
The recommended first deployment is cheap-lab. It proves the landing-zone structure while keeping high-cost services off.
Expected outcome:
| Capability | Expected cheap-lab behavior |
|---|---|
| Hub-spoke topology | Hub, identity, management, shared, and selected workload VNets are planned |
| Management access | No public RDP by default |
| Shared services | Key Vault and Storage available; private endpoint path supported |
| Monitoring | Log Analytics enabled with lab-safe retention and quota |
| Governance | Cost controls and policy concepts documented; expensive controls remain opt-in |
| CI/CD | OIDC-based GitHub Actions plan and controlled apply/destroy |
Run from the repository root:
git status --short
terraform version
terraform fmt -check -recursive -diff
terraform init -backend=false
terraform validate -no-colorExpected result:
| Check | Pass condition |
|---|---|
| Git status | Only intentional local edits appear |
| Terraform version | >= 1.9.0 |
| Format | No files listed in diff |
| Init | Provider plugins initialize without backend |
| Validate | Success! The configuration is valid. |
Stop if formatting or validation fails. Fix code before preparing backend state or cloud deployment.
Backend source: backend.tf
Required GitHub secrets:
| Secret | Example format | Notes |
|---|---|---|
TF_STATE_RG |
rg-terraform-state-wus2 |
Resource group containing state account |
TF_STATE_SA |
sttfstateexample |
Storage account name only |
AZURE_CLIENT_ID |
GUID value in secret store | Do not place in docs or tfvars |
AZURE_TENANT_ID |
GUID value in secret store | Treat as sensitive if your org requires it |
AZURE_SUBSCRIPTION_ID |
GUID value in secret store | Treat as sensitive if your org requires it |
State storage should have:
- Soft delete or versioning enabled where supported.
- RBAC-limited write access.
- No public sample access keys committed.
- A backup container or backup action that creates one before apply or destroy.
The workflow uses OIDC instead of long-lived Azure credentials JSON.
Minimum GitHub workflow permission:
permissions:
id-token: write
contents: write
pull-requests: write
security-events: writeExpected Azure federated credential shape:
| Field | Expected value |
|---|---|
| Issuer | https://token.actions.githubusercontent.com |
| Audience | api://AzureADTokenExchange |
| Subject | Repository, branch, pull request, or environment subject matching the workflow |
Evidence to keep:
- Screenshot of successful Azure Login step.
- Workflow run URL.
- Confirmation that
AZURE_CREDENTIALSis not required.
GitHub UI:
- Open Terraform Pipeline.
- Select
Run workflow. - Choose
environment = cheap-lab. - Choose
action = plan. - Leave
destroy_confirmempty.
GitHub CLI:
gh workflow run "Terraform Pipeline" --repo Jamonygr/azure-landing-zone-lab -f environment=cheap-lab -f action=planPlan review must include:
| Evidence | What to check |
|---|---|
| Plan counts | Unexpected deletes must be zero |
| Public IP resources | Only expected public entry points appear |
| RDP exposure | No 0.0.0.0/0 RDP and no LB RDP NAT by default |
| PaaS access | SQL public access disabled when SQL is enabled |
| Private DNS | Expected zones and links exist when private endpoints are enabled |
| Cost estimate | Expensive resources are intentionally disabled |
| OPA results | No deny findings |
Use Terraform Plan Review Guide for a deeper review checklist.
Apply only after the plan is reviewed:
gh workflow run "Terraform Pipeline" --repo Jamonygr/azure-landing-zone-lab -f environment=cheap-lab -f action=applyExpected apply sequence:
- OIDC login succeeds.
- Backend initializes against the selected state key.
- State backup runs before apply.
- The saved plan artifact is applied.
- Inventory, changelog, and metrics actions run where configured.
Record:
- Workflow run URL.
- Plan artifact name.
- Apply job result.
- State backup result.
- Resource inventory artifact.
Use Azure Portal Validation Evidence to collect proof.
Minimum checks:
| Area | Validation |
|---|---|
| Resource groups | Expected groups exist with standard tags |
| Networking | Hub and spokes exist with expected CIDRs |
| Peering | Hub-to-spoke and spoke-to-hub peerings are connected |
| Management | Jumpbox public IP is absent unless intentionally enabled |
| Shared services | Key Vault and Storage are deployed as expected |
| Private endpoints | Private IPs exist in the shared PE subnet when enabled |
| Monitoring | Log Analytics workspace and diagnostic settings exist |
| Cost | Budget or cost alert exists when cost management is enabled |
Recommended non-destructive commands:
az group list --query "[?contains(name, 'azlab')].{name:name, location:location}" -o table
az network vnet list --query "[].{name:name, rg:resourceGroup, address:addressSpace.addressPrefixes}" -o table
az monitor log-analytics workspace list --query "[].{name:name, rg:resourceGroup}" -o tablePrivate DNS checks require a VM or runner with access to the peered network. Do not test private endpoints from a public internet client and treat failed public resolution as expected.
For a throwaway lab, destroy after validation:
gh workflow run "Terraform Pipeline" --repo Jamonygr/azure-landing-zone-lab -f environment=cheap-lab -f action=destroy -f destroy_confirm=DESTROYBefore destroy:
- Confirm selected environment.
- Confirm no shared state key is reused by another lab.
- Confirm state backup succeeded.
- Confirm destroy environment approval is required.
After destroy:
- Confirm resource groups are deleted or intentionally retained.
- Confirm cost view stops growing.
- Keep sanitized workflow evidence and inventory artifacts.
For a complete lab proof package, keep sanitized copies of:
| Evidence | Location |
|---|---|
| Successful plan run | GitHub Actions run URL |
| Successful apply run | GitHub Actions run URL |
| Terraform output summary | Workflow artifact or sanitized terminal output |
| Azure resource inventory | Workflow artifact or Azure CLI export |
| Portal screenshots | Resource groups, VNets, Log Analytics, policy/cost pages |
| Validation checklist | Azure Portal Validation Evidence |
Next page: Terraform Plan Review Guide
- Architecture Overview
- Full Environment Inventory
- Network Topology
- Shared Services
- Workloads
- Module Reference
- Security Model
- Security Operations
- Identity and Access
- Governance and Policy
- Production Readiness Review
- Monitoring and Diagnostics
- Operations Runbooks
- Azure Portal Validation Evidence
- Cost Management
- Disaster Recovery and Resilience