TenantZero AI Architecture¶
Deployment Goal¶
Deploy a private AI platform foundation in a customer Azure tenant using Terraform and Azure-native services only.
What Gets Deployed¶
- Environment-isolated resource groups: core, network, security, observability
- VNet with subnet segmentation (
snet-pe,snet-compute,snet-management, optionalsnet-data) - Private DNS zones and VNet links for Private Link resolution
- Key Vault with RBAC, purge protection, soft delete, and private endpoint
- Azure OpenAI with public access disabled and private endpoint
- Azure AI Search with private endpoint
- Data profile: Cosmos DB or PostgreSQL Flexible Server (private mode)
- Log Analytics and diagnostics settings
- Optional private AKS cluster
- Optional policy baseline assignments
Module Map¶
Foundation (modules/foundation/)¶
naming: deterministic naming helperstags: shared tag baseline (configurablemanaged_by,workload,cost_center)resource_group: RG provisioning
Networking (modules/networking/)¶
vnet: VNet, subnets, NSGsprivate_dns: private DNS zones and links (configurable registration)private_endpoint: generic PE helper
Security (modules/security/)¶
key_vault: vault + PE + optional CMK (configurable network ACLs, RBAC)
AI (modules/ai/)¶
openai: Azure OpenAI + model deployments (managed identity, local auth disabled)ai_search: AI Search service
Data (modules/data/)¶
cosmos: Cosmos DB (configurable consistency, backup type, offer type)postgres: PostgreSQL Flexible Server (Entra auth, private access, configurable SKU)
Observability (modules/observability/)¶
log_analytics: Log Analytics workspace (configurable SKU, retention)diagnostics: diagnostic settings fan-out
Governance (modules/governance/)¶
policy_baseline: custom policy definitions and assignments
Compute (modules/compute/)¶
aks_private: private AKS deployment (managed identity)
Module Contract¶
Every resource module must:
- Accept
resource_group_name,location, andtagsas inputs - Expose meaningful outputs (resource IDs, endpoints, FQDNs)
- Never reference sibling modules or assume naming patterns
- Document all defaults explicitly (SKU, capacity, access toggles)
Utility modules (naming, tags) and scope-based modules (policy_baseline, diagnostics) follow adapted contracts appropriate to their function.
Composition Pattern¶
Root Stack (envs/<env>/main.tf)
|
+-- foundation/naming (generates names)
+-- foundation/tags (generates tag map)
+-- foundation/resource_group (creates RGs)
+-- networking/vnet (VNet, subnets, NSGs)
+-- networking/private_dns (DNS zones, VNet links)
+-- security/key_vault (vault resource)
+-- networking/private_endpoint (PE for Key Vault, OpenAI, Search, Cosmos)
+-- ai/openai (OpenAI + deployments)
+-- ai/ai_search (Search service)
+-- data/cosmos or data/postgres (data profile)
+-- observability/log_analytics (workspace)
+-- observability/diagnostics (fan-out to Log Analytics)
+-- governance/policy_baseline (policy assignments)
+-- compute/aks_private (optional AKS)
The root stack defines environment intent, calls modules, and injects dependencies. Modules never call each other directly. Private endpoints are composed at the root level, not inside service modules.
Environment Model¶
Each environment under envs/<env>/ is a separate root stack with:
- Independent Terraform state file
- Independent backend configuration
- Independent resource names and model deployments
- Independent vaults and data services
- No cross-environment data plane references
Data Flow Boundaries¶
- No public ingress is required for core PaaS services
- Private endpoints land in
snet-pe - DNS resolution for service FQDNs is internalized through private zones
- Diagnostics route to Log Analytics for centralized audit and operations