Azure-Samples / Azure-Samples/tutor

[Sprint 2] Extract stacks/data-ai/ — Cosmos DB + AI Foundry

Open
#121 1 comment 0 reactions 0 assignees View on GitHub
component:foundry component:terraform priority:P1 type:architecture
Dominant language
Python
Stars
17
Forks
8
PR merge metrics
No merged PRs in 30d

Description

## Summary

Extract Cosmos DB (account, database, containers, private endpoint) and AI Foundry (AVM module) from `infra/terraform/main.tf` into a new stacked root module at `infra/terraform/stacks/data-ai/`.

**Parent epic**: #119

## Business Context

The AI Foundry AVM module (Cognitive Services + Hub + Project + 2 model deployments) can take 20–30 minutes on first deployment. Cosmos DB provisioning with private endpoint adds another ~5 min. Currently these compete with ACA app creation for control-plane quota in the same `terraform apply`. Isolating them allows:
- Parallel provisioning with ACA apps (both depend only on foundation)
- Independent retry on Foundry 409 `RequestConflict` errors (#117)
- Reduced blast radius — Foundry failure doesn't block ACA app creation

## Scope

### Resources to extract

| Current address | Notes |
|---|---|
| `azurerm_cosmosdb_account.main` | Includes `public_network_access = "Disabled"` |
| `azurerm_cosmosdb_sql_database.main` | |
| `azurerm_cosmosdb_sql_container.containers` (for_each × 14) | |
| `azurerm_private_endpoint.cosmos` | References foundation VNet subnet |
| `module.ai_foundry` | AVM module `Azure/avm-ptn-aiml-ai-foundry/azurerm` v0.10.0 — creates ~8 child resources internally |

**Stay in foundation** (shared VNet resources):
- `azurerm_private_dns_zone.cosmos`
- `azurerm_private_dns_zone_virtual_network_link.cosmos`

### Files to create

- `infra/terraform/stacks/data-ai/main.tf`
- `infra/terraform/stacks/data-ai/variables.tf`
- `infra/terraform/stacks/data-ai/outputs.tf` — `cosmos_endpoint`, `cosmos_database_name`, `ai_foundry_id`, `project_endpoint`, `model_deployment_name`, `model_reasoning_deployment`, `ai_services_endpoint`
- `infra/terraform/stacks/data-ai/providers.tf`

### State migration

**High risk** — the AI Foundry AVM module manages ~8 internal resources. Migration steps:
1. `terraform state list | grep ai_foundry` to enumerate all AVM-managed addresses
2. `terraform state mv` each resource from monolith → data-ai state
3. Do the same for all Cosmos resources + private endpoint
4. Validate with `terraform plan` on both stacks — expect 0 changes

## Input Variables

| Variable | Source |
|----------|--------|
| `environment` | Workflow env |
| `name_prefix` / `normalized_prefix` | Foundation output or computed |
| `resource_group_name` / `resource_group_id` | Foundation output |
| `location` / `foundry_location` | Foundation output / variable |
| `cosmos_private_endpoint_subnet_id` | Foundation output |
| `cosmos_private_dns_zone_ids` | Foundation output (list) |
| `storage_account_id` | Foundation output |
| `cosmos_containers` | Variable (same map as current) |
| `random_suffix` | Foundation output |

## Acceptance Criteria

- [ ] `terraform plan` on `stacks/data-ai/` shows 0 changes after state migration
- [ ] `terraform plan` on foundation shows 0 changes after resource removal
- [ ] Cosmos DB private endpoint resolves correctly through foundation VNet
- [ ] AI Foundry model deployments are accessible from ACA apps
- [ ] Cosmos containers match production schema (14 containers)
- [ ] Stack is independently `terraform plan`-able for drift detection

## Risk

| Risk | Likelihood | Impact | Mitigation |
|------|-----------|--------|------------|
| Cosmos data loss during state move | Low | **Critical** | `removed` block with `destroy = false`; verify plan before apply; backup state file |
| AVM module state fragmentation | Medium | Medium | Enumerate all child resources via `terraform state list`; move atomically |
| Private endpoint loses DNS resolution | Low | High | DNS zone stays in foundation; only the PE resource moves |

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.