AI Platform: Platform Modules¶
This page is for the platform team. It describes the five Terraform modules of the solution, their main inputs and how they are meant to be combined. The platform team is XMMS or your own team, see Operating models.
Modules only
The source delivers modules. The deployment code that calls them per environment ("deploy roots") is planned for a later phase. Deployment order when it exists: shared platform first, then projects, then workloads.
Requirements¶
| Item | Value |
|---|---|
| Terraform | >= 1.12, < 2.0 |
| AzureRM provider | >= 4.0.0, < 5.0 |
| AzAPI provider | >= 2.6.1, < 3.0 |
| Azure AD provider | ~> 2.47, < 3.0 |
| Naming module | Azure/naming/azurerm ~> 0.4 |
| Backend | azurerm with use_azuread_auth = true; storage account, container and key are passed at terraform init, nothing is committed |
| Authentication | Azure CLI session with sufficient permissions |
The azurerm version constraint (< 5.0) matters when you plan a provider upgrade, see Known issues.
Lock files are committed to the repository.
Overview¶
| Module | Type | Creates |
|---|---|---|
foundry_account |
Resources | Foundry account, its identity, optional private endpoint |
foundry_project |
Resources | Project, identity, storage, Application Insights, connections, capability host, role assignments |
workload_identity |
Resources | User-assigned identity and role assignments |
platform_data |
Data only | Lookup of shared platform resources |
project_data |
Data only | Lookup of one project and its identity |
flowchart LR
pd["platform_data"] --> pdata["project_data"]
pd --> fp["foundry_project"]
fa["foundry_account"] --> fp
fp --> wi["workload_identity"]
pdata --> wl["workload"]
wi --> wl
foundry_account¶
Creates the shared account. Inputs:
| Input | Required | Description |
|---|---|---|
name |
Yes | Account name. Also used as custom subdomain. The identity is named <name>-identity, the private endpoint <name>-pe. |
resource_group_id |
Yes | Parent resource group ID |
location |
Yes | Azure region |
integration_subnet_id |
Yes | Subnet for agent network injection |
endpoint_subnet_id |
No | Subnet for the private endpoint. Without it, no private endpoint is created. |
tags |
No | Tags |
Outputs: id, name, endpoint, openai_endpoint, identity_client_id, identity_principal_id.
foundry_project¶
Creates one project. Two modes:
| Mode | When | Result |
|---|---|---|
| Decoupled | account_id is set |
Only the project and its resources, in the existing account. Use this with the shared platform account. |
| Standalone | account_id is null (default) |
Also creates an account, its identity, a private endpoint and diagnostic settings. Kept for backward compatibility. |
| Input | Required | Description |
|---|---|---|
project_name |
Yes (default null in code) |
Name of the project. Also the suffix for resource names. |
location |
Yes | Azure region |
integration_subnet_id |
Yes | Agent integration subnet |
endpoint_subnet_id |
Yes | Subnet for private endpoints |
log_analytics_workspace_id |
Yes | Workspace for Application Insights (and diagnostics in standalone mode) |
cosmosdb_account_id |
Yes | Cosmos DB account for agent threads |
ai_search_id |
Yes | AI Search service as vector store |
account_id |
No | Existing account |
owner_group_id, contributor_group_id, reader_group_id |
Effectively yes | Entra ID groups, see Access and RBAC |
tags |
No | Tags |
Outputs: foundry (account ID, name, identity; identity values are null in decoupled mode), foundry_project (ID, name,
identity) and used_resources (storage account, Cosmos DB, AI Search).
Sequence inside the module, which explains the waits you see in a plan:
- Resource group, identities, Application Insights, storage account and its private endpoint.
- The project, then a 10 second wait for the project identity to be available in Entra ID.
- Connections (storage, Cosmos DB, AI Search, Application Insights) and the role assignments on the data stores.
- A 60 second wait for role assignments to take effect.
- The capability host
caphostproject-<project>. - The Cosmos DB SQL role assignments on the collections the capability host created.
platform_data and project_data¶
Data-only modules, no resources.
platform_data has no inputs. It looks up the platform resource group, the Foundry account, container registry,
Container Apps environment, Cosmos DB, AI Search, two storage accounts (platform and data), Key Vault, Log Analytics
workspace, the spoke VNet, the private endpoint subnet and the Foundry integration subnet, and exposes IDs, names and
endpoints. It also outputs the owner, contributor and reader group IDs.
Resource names are hard-coded
The names in platform_data are written as local values in main.tf for one platform deployment (one region,
production). Another deployment, region or environment needs a change of those values, or the module has to be
changed to take inputs. See Known issues.
project_data takes project_name and uses platform_data to find the account. It outputs project_id, project_name,
project_endpoint, identity_client_id and identity_principal_id. It finds the project identity by the naming
convention id-<project>-foundry-project in the project resource group, so a project created outside foundry_project
must follow that convention.
workload_identity¶
| Input | Required | Description |
|---|---|---|
name |
Yes | Identity name |
location |
Yes | Region |
resource_group_name |
Yes | Resource group of the identity |
role_assignments |
No | List of objects with scope and role_definition_name |
tags |
No | Tags |
Outputs: id, client_id, principal_id. Each assignment is keyed on scope plus role name.
Create a project: checklist¶
Use this as a guide when a request for a new project arrives. Adapt it to your deployment code.
| Step | Check |
|---|---|
| 1 | The name is short (maximum 8 characters) and unique on the platform |
| 2 | Region and environment are allowed on your platform |
| 3 | The three groups exist and have the right owners (Access, groups and PIM) |
| 4 | The shared Cosmos DB, AI Search, Log Analytics workspace and the two subnets exist |
| 5 | Required private DNS zones resolve (see Architecture) |
| 6 | The needed models are deployed in the account and quota is available |
| 7 | Plan shows the expected project resources only, then apply through your normal pipeline and review: Change workflow |