A prescriptive guide to designing Azure Landing Zones that host AI services securely, at scale, and aligned with the Cloud Adoption Framework (CAF). Covers management groups, subscriptions, networking, identity, governance, and platform services for enterprise AI.
An Azure Landing Zone is a pre-provisioned, governed environment where workloads are deployed. It provides the foundational building blocks — networking, identity, governance, security, and management — so application teams can focus on building rather than plumbing.
For AI workloads, the landing zone must address unique requirements: high-bandwidth data pipelines, GPU compute isolation, model governance, Private Endpoint density, and OpenAI quota management.
Hosts shared services: networking, identity, DNS, monitoring, security tools. Managed by the platform team.
Hosts workload-specific resources: AI services, compute, storage, app code. Owned by workload teams.
Unmanaged experimentation zone with no connectivity to production. For AI prototyping and hackathons.
| Requirement | Standard Workload | AI Workload |
|---|---|---|
| Compute | General-purpose VMs, App Service | GPU clusters (NC/ND series), Databricks VNet-injected, managed endpoints |
| Network | 2-3 subnets, basic NSGs | 5-8 subnets, /22 for Databricks, PE-dense /24 subnets, UDR for Firewall |
| Private Endpoints | 2-3 PEs | 6-12 PEs (OpenAI, Search, ML, Storage Ã-N, KV, ACR) |
| DNS | 1-2 Private DNS Zones | 5-8 zones (privatelink.openai, search, blob, dfs, vaultcore, ml, acr) |
| Data | Single storage account | Multi-account medallion (raw/curated/serving), feature stores, model registries |
| Quota | vCPU quotas | OpenAI TPM/RPM, GPU quotas, Databricks DBU, AI Search units |
| Governance | Cost tags, RBAC | Model lineage, responsible AI, content filtering, data classification |
| Egress | NAT Gateway | Azure Firewall with TLS inspection, threat intel, application rules |
graph TB
ROOT["Tenant Root Group"]
ROOT --> PLATFORM["Platform"]
ROOT --> LANDING["Landing Zones"]
ROOT --> SANDBOX["Sandbox"]
ROOT --> DECOM["Decommissioned"]
PLATFORM --> MGMT["Management<br/>Log Analytics, Automation<br/>Defender for Cloud"]
PLATFORM --> CONN["Connectivity<br/>Hub VNet, Firewall<br/>DNS, ExpressRoute"]
PLATFORM --> ID["Identity<br/>Entra ID, Domain Ctrlrs<br/>Conditional Access"]
LANDING --> CORP["Corp (Connected)<br/>VNet-peered workloads"]
LANDING --> ONLINE["Online (Internet)<br/>Public-facing apps"]
LANDING --> AI["AI & ML<br/>AI Workloads"]
AI --> AIPROD["AI-Prod<br/>Production AI services"]
AI --> AIDEV["AI-NonProd<br/>Dev/Test AI services"]
CORP --> CORPSUB["App Subscriptions"]
SANDBOX --> SBX["Sandbox Subs<br/>No connectivity"]
style AI fill:#0d6efd,color:#fff,stroke:#0d6efd
style AIPROD fill:#198754,color:#fff
style AIDEV fill:#ffc107,color:#000
style PLATFORM fill:#6c757d,color:#fff
style CONN fill:#0dcaf0,color:#000
The AI & ML management group sits under Landing Zones and contains dedicated subscriptions for AI workloads. This separation enables:
graph TB
subgraph MGMT_SUB["Management Subscription"]
LAW["Log Analytics<br/>Workspace"]
AUTO["Automation<br/>Account"]
DEF["Defender for<br/>Cloud"]
end
subgraph CONN_SUB["Connectivity Subscription"]
subgraph HubVNet["Hub VNet 10.0.0.0/16"]
FW["Azure Firewall<br/>Premium"]
BASTION["Azure Bastion"]
GW["VPN / ER<br/>Gateway"]
DNS_RES["DNS Private<br/>Resolver"]
end
DNS_ZONES["Private DNS<br/>Zones (8+)"]
end
subgraph AI_SUB["AI Landing Zone Subscription"]
subgraph AIVNet["AI Spoke VNet 10.10.0.0/16"]
subgraph AI_SVC["AI Services Subnet /24"]
AOAI["Azure OpenAI"]
AIS["AI Search"]
AML["Azure ML"]
end
subgraph COMPUTE["Compute Subnet /20"]
AKS["AKS / App Svc"]
DBX["Databricks<br/>VNet-injected"]
end
subgraph DATA_SUB["Data Subnet /24"]
ADLS["ADLS Gen2<br/>(x multiple)"]
ACR["Container<br/>Registry"]
end
subgraph PE_SUB["PE Subnet /24"]
PE["Private<br/>Endpoints (6-12)"]
end
end
KV["Key Vault"]
AI_MON["App Insights"]
end
GW -->|"ExpressRoute /<br/>VPN"| OnPrem["On-Premises"]
HubVNet -->|"VNet Peering"| AIVNet
PE --> AOAI
PE --> AIS
PE --> AML
PE --> ADLS
AI_SVC --> FW
COMPUTE --> FW
AI_MON --> LAW
DEF --> AI_SUB
DNS_ZONES --> PE_SUB
Conceptual: Hub-Spoke topology with dedicated AI Landing Zone subscription peered to the Connectivity Hub
AI Landing Zones use a hub-spoke network model. The Connectivity subscription owns the Hub VNet (Firewall, DNS, Gateway). Each AI workload spoke peers into the Hub for controlled egress and DNS resolution.
graph LR
subgraph Hub["Hub VNet 10.0.0.0/16"]
FW["Firewall<br/>10.0.0.0/26"]
BASTION["Bastion<br/>10.0.1.0/26"]
GW["Gateway<br/>10.0.2.0/27"]
DNS["DNS Resolver<br/>10.0.3.0/28"]
end
subgraph Spoke1["AI Spoke 1 — 10.10.0.0/16"]
S1_AI["AI Services /24"]
S1_PE["Private Endpoints /24"]
S1_COMP["Compute /20"]
S1_DATA["Data /24"]
end
subgraph Spoke2["AI Spoke 2 — 10.20.0.0/16"]
S2_AI["AI Services /24"]
S2_PE["Private Endpoints /24"]
S2_COMP["Compute /20"]
end
Hub -->|"Peering"| Spoke1
Hub -->|"Peering"| Spoke2
S1_COMP -->|"UDR 0.0.0.0/0"| FW
S2_COMP -->|"UDR 0.0.0.0/0"| FW
A typical AI spoke VNet (10.10.0.0/16 = 65,536 IPs) needs careful subnet planning. Databricks alone consumes 2Ã- /22 subnets (2,048 IPs). Private Endpoints and AKS are the next largest consumers.
| Subnet | CIDR | IPs | Purpose | Delegation / Notes |
|---|---|---|---|---|
| snet-ai-pe | 10.10.0.0/24 | 251 | Private Endpoints for AI services | No delegation; NSG: VNet-only inbound |
| snet-data-pe | 10.10.1.0/24 | 251 | Private Endpoints for data services | No delegation; NSG: VNet-only inbound |
| snet-aks | 10.10.16.0/20 | 4,091 | AKS node pool (system + user + GPU) | No delegation; Azure CNI overlay or kubenet |
| snet-dbx-public | 10.10.32.0/22 | 1,019 | Databricks public subnet | Microsoft.Databricks/workspaces delegation |
| snet-dbx-private | 10.10.36.0/22 | 1,019 | Databricks private subnet | Microsoft.Databricks/workspaces delegation |
| snet-app | 10.10.40.0/24 | 251 | App Service VNet Integration | Microsoft.Web/serverFarms delegation |
| snet-ml-compute | 10.10.41.0/24 | 251 | Azure ML compute instances/clusters | No delegation; NSG required |
| snet-mgmt | 10.10.42.0/26 | 59 | Management / jumpbox / Bastion | No delegation |
| Total Allocated | ~7,192 | 11% of /16 used — room for growth | ||
Every service uses System-Assigned Managed Identity for zero-credential authentication. No API keys stored in app settings.
| Service | Identity Grants |
|---|---|
| AKS / App Service | Cognitive Services OpenAI User, Search Index Data Reader |
| Azure ML | Storage Blob Data Contributor, Key Vault Secrets User |
| AI Search | Storage Blob Data Reader (indexer), Cognitive Services OpenAI User |
| Databricks | Storage Blob Data Contributor (on ADLS accounts) |
Follow least-privilege with custom roles where built-in roles are too broad.
| Persona | Scope | Role |
|---|---|---|
| Platform Team | AI MG | Owner / Contributor |
| AI Team Lead | AI Subscription | Contributor |
| Data Scientist | Resource Group | ML Operator + Blob Data Contributor |
| App Developer | Resource Group | Cognitive Services OpenAI User |
| SecOps | AI MG | Security Reader + Log Analytics Reader |
Azure Policies assigned at the AI & ML management group enforce guardrails that prevent misconfigurations before they reach production.
| Policy | Effect | Purpose |
|---|---|---|
| Cognitive Services should use private link | Deny | Prevent OpenAI / AI Search with public endpoints |
| Storage accounts should use private link | Deny | Force ADLS Gen2 behind private endpoints |
| Key Vault should use RBAC authorization | Deny | Prevent access-policy-based Key Vaults |
| Azure OpenAI should have content filtering | Audit | Ensure responsible AI guardrails |
| Diagnostic settings should be enabled | DeployIfNotExists | Auto-configure diagnostics to Log Analytics |
| Deploy Defender for AI services | DeployIfNotExists | Enable threat detection on cognitive services |
| AKS clusters should use Azure RBAC | Deny | Prevent local Kubernetes accounts |
| Allowed locations: Canada Central | Deny | Data residency compliance |
| Require resource tags (CostCenter, Owner, Environment) | Deny | Cost tracking and accountability |
| Storage TLS minimum version 1.2 | Deny | Encryption in transit |
CostCenter
Owner
Environment
DataClassification
AIWorkload
ModelName
ResponsibleAIReview
AI workloads are data-intensive. The landing zone must accommodate multiple storage accounts, feature stores, model registries, and data pipelines — all with private access.
graph LR
subgraph Ingestion
EH["Event Hubs"]
ADF["Data Factory"]
STREAM["Stream<br/>Analytics"]
end
subgraph Storage["ADLS Gen2 Medallion"]
RAW["Raw Zone<br/>landing / raw / archive"]
CUR["Curated Zone<br/>silver / gold / delta"]
SRV["Serving Zone<br/>embeddings / vectors"]
end
subgraph Processing
DBX["Databricks<br/>ETL + Feature Eng"]
AML2["Azure ML<br/>Training Pipelines"]
end
subgraph AI_Layer["AI Ready"]
AIS2["AI Search<br/>Vector Index"]
AOAI2["Azure OpenAI<br/>Embeddings + LLM"]
end
EH --> RAW
ADF --> RAW
RAW --> DBX
DBX --> CUR
CUR --> DBX
DBX --> SRV
SRV --> AIS2
SRV --> AOAI2
AML2 --> CUR
STREAM --> RAW
Immutable landing area. Data arrives here from Event Hubs, Data Factory, or direct upload.
Cleansed, transformed, business-ready data. Delta Lake provides ACID transactions.
AI-ready data: embeddings, vector indexes, model artifacts, and documents for RAG.
| Service | Role in LZ | Deployment Model | Key Limits | Private Endpoint Zone |
|---|---|---|---|---|
| Azure OpenAI | LLM inference + embeddings | S0, GlobalStandard models | 30 deployments, 240K TPM (GPT-4o) | privatelink.openai.azure.com |
| Azure AI Search | Vector + semantic search | Standard S1 (25GB), S2 (100GB) | 50 indexes, 12 replicas max | privatelink.search.windows.net |
| Azure Machine Learning | Model registry, training, endpoints | Workspace (Free) + compute | 800 endpoints, 200 compute clusters | privatelink.api.azureml.ms |
| Azure Databricks | ETL, feature eng, training | Premium, VNet-injected | Workspace-level quotas | privatelink.databricks.azure.net |
| Container Registry | ML model container images | Premium (geo-replicated) | 500 repos, 500GB storage | privatelink.azurecr.io |
| API Management | Gateway for AI APIs | Standard v2 / Consumption | 4,000 req/sec (Std v2) | privatelink.azure-api.net |
Each of the 7 Azure AI Deployment Patterns maps to a specific landing zone topology. Use this table to choose the right foundation:
| Pattern | LZ Type | Subscriptions | VNet Model | Firewall | Best For | |
|---|---|---|---|---|---|---|
| 1. Centralized Hub | Platform LZ (Hub) | 1 shared AI sub | Hub VNet + spoke peering | Optional | Single-team, cost-efficient | Details |
| 2. Decentralized Spoke | App LZ (per spoke) | N subs (1/team) | Isolated VNets | Standard | Data isolation, autonomy | Details |
| 3. Hybrid Central-Spoke | Platform + App LZ | 1 hub + N spoke subs | Hub-spoke peering | Standard | Shared models + spoke RAG | Details |
| 4. AI Factory / MLOps | Dedicated AI LZ | 1 AI Factory sub | Single VNet, 5+ subnets | Optional | Full ML lifecycle | Details |
| 5. Serverless | Online LZ / Sandbox | 1 sub | No VNet (public PaaS) | None | PoC, hackathons, MVP | Details |
| 6. Secure Private | Corp LZ (isolated) | 1 dedicated sub | Fully private VNet | Premium | Regulated (HIPAA, PCI) | Details |
| 7. Data-Centric Lakehouse | Dedicated AI LZ | 1 AI + data sub | Single VNet, 6+ subnets | Optional | Data platform + AI | Details |
graph TD
START["Start: New AI Workload"] --> Q1{"Need private<br/>network isolation?"}
Q1 -->|"No"| Q2{"Production or<br/>PoC / internal?"}
Q2 -->|"PoC"| P5["Pattern 5<br/>Serverless AI<br/>Online LZ / Sandbox"]
Q2 -->|"Production"| Q3{"Multiple teams<br/>sharing AI?"}
Q1 -->|"Yes"| Q4{"Zero Trust /<br/>regulated data?"}
Q4 -->|"Yes"| P6["Pattern 6<br/>Secure Private AI<br/>Corp LZ"]
Q4 -->|"No"| Q5{"Data-intensive<br/>with Databricks?"}
Q5 -->|"Yes"| Q6{"Full ML lifecycle<br/>needed?"}
Q6 -->|"Yes"| P4["Pattern 4<br/>AI Factory / MLOps<br/>Dedicated AI LZ"]
Q6 -->|"No"| P7["Pattern 7<br/>Data-Centric Lakehouse<br/>Dedicated AI LZ"]
Q5 -->|"No"| Q3
Q3 -->|"Yes"| Q7{"Teams need<br/>full isolation?"}
Q7 -->|"Yes"| P2["Pattern 2<br/>Decentralized Spoke<br/>App LZ per team"]
Q7 -->|"No"| Q8{"Teams need own<br/>search / RAG?"}
Q8 -->|"Yes"| P3["Pattern 3<br/>Hybrid Central-Spoke<br/>Platform + App LZ"]
Q8 -->|"No"| P1["Pattern 1<br/>Centralized Hub<br/>Platform LZ"]
Q3 -->|"No"| P1
style P1 fill:#0d6efd,color:#fff
style P2 fill:#0dcaf0,color:#000
style P3 fill:#198754,color:#fff
style P4 fill:#6f42c1,color:#fff
style P5 fill:#fd7e14,color:#fff
style P6 fill:#dc3545,color:#fff
style P7 fill:#20c997,color:#fff