Provision Azure Infrastructure
This provisions the cloud infrastructure Confident AI runs on: a private AKS cluster, a PostgreSQL Flexible Server, a Storage account with two Blob containers, and the private networking that ties them together. When it finishes you will have a running cluster and a set of outputs to feed into the Helm chart on the next page.
The azurerm provider needs the subscription set explicitly. Set it and your region once:
az account set --subscription "<your-subscription>"
export ARM_SUBSCRIPTION_ID=$(az account show --query id -o tsv)
export LOCATION=centralusCreate the resource group and network (optional)
AKS needs a subnet of its own, and PostgreSQL Flexible Server needs a separate subnet delegated to it. Run the blocks in order.
Create the resource group:
az group create --name confident-prod-rg --location $LOCATIONCreate the VNet with the AKS subnet:
az network vnet create \ --resource-group confident-prod-rg --name confident-prod-vnet \ --address-prefixes 10.40.0.0/16 \ --subnet-name aks --subnet-prefixes 10.40.0.0/20Add a second subnet delegated to PostgreSQL Flexible Server. It must hold nothing else:
az network vnet subnet create \ --resource-group confident-prod-rg --vnet-name confident-prod-vnet \ --name postgres --address-prefixes 10.40.16.0/28 \ --delegations Microsoft.DBforPostgreSQL/flexibleServersPrint the network IDs to paste into the Terraform config:
echo "confident_virtual_network_id = \"$(az network vnet show -g confident-prod-rg -n confident-prod-vnet --query id -o tsv)\"" echo "confident_aks_subnet_id = \"$(az network vnet subnet show -g confident-prod-rg --vnet-name confident-prod-vnet -n aks --query id -o tsv)\"" echo "confident_database_subnet_id = \"$(az network vnet subnet show -g confident-prod-rg --vnet-name confident-prod-vnet -n postgres --query id -o tsv)\""Mirror the code sandbox image (required)
Code-based and transformer metrics run in a sandboxed Azure Function, which pulls the
confident-code-sandbox-azureimage from an Azure Container Registry you own. Mirror the public image into your ACR. The module expects the repository nameconfident-code-sandbox, so tag it that way.Create the ACR and log Docker in to it (the name must be globally unique and lowercase):
az acr create --resource-group confident-prod-rg --name <youracr> --sku Basic az acr login --name <youracr>Pull the public image and push it to your ACR:
docker pull confidentai/confident-code-sandbox-azure:latest docker tag confidentai/confident-code-sandbox-azure:latest <youracr>.azurecr.io/confident-code-sandbox:latest docker push <youracr>.azurecr.io/confident-code-sandbox:latestWrite the Terraform config
Create a
main.tfthat references the published module, then fill in the IDs from the earlier steps. What each variable does:- Resource group and network:
confident_resource_group_name,confident_azure_region, and the network IDs from the network step. - Naming:
confident_environmentandconfident_environment_codestamp theprodnaming convention onto every resource. - Access:
confident_public_aksexposes the cluster API to your machine; set itfalsefor a private-only endpoint. - Managed services:
confident_create_key_vaultandconfident_managed_redis_enabledturn on the recommended secret store and Redis, andconfident_redis_private_endpoint_subnet_idplaces Redis's private endpoint (theakssubnet works). - Code executor:
confident_acr_login_serveris the ACR holding the image you mirrored. If the Function cannot pull from a private ACR, also setconfident_acr_admin_usernameandconfident_acr_admin_password.
provider "azurerm" { features {} } module "confident_ai" { source = "confident-ai/confident-ai/azurerm" version = "~> 0.1" confident_resource_group_name = "confident-prod-rg" confident_azure_region = "centralus" confident_virtual_network_id = "/subscriptions/.../virtualNetworks/confident-prod-vnet" confident_aks_subnet_id = "/subscriptions/.../subnets/aks" confident_database_subnet_id = "/subscriptions/.../subnets/postgres" confident_environment = "prod" confident_environment_code = "p" confident_public_aks = true confident_create_key_vault = true confident_managed_redis_enabled = true confident_redis_private_endpoint_subnet_id = "/subscriptions/.../subnets/aks" confident_code_executor_enabled = true confident_acr_login_server = "<youracr>.azurecr.io" } output "helm_values" { value = module.confident_ai.helm_values sensitive = true }- Resource group and network:
Configure remote state (optional)
terraform { backend "azurerm" { resource_group_name = "confident-prod-rg" storage_account_name = "confidenttfstate" container_name = "tfstate" key = "confident-ai/azure.tfstate" } }Apply
terraform init terraform plan terraform applyCreating the AKS cluster and Flexible Server takes roughly 15 to 20 minutes.
Connect to the cluster
eval "$(terraform output -raw configure_kubectl)" kubectl get nodesAKS has a default storage class (
managed-csi), so the in-cluster ClickHouse and Redis disks work out of the box.Read the outputs
The Helm chart on the next page needs these values.
terraform output helm_valuesprints a ready-to-paste snippet, or read them individually. The comment on each line is the Helm value it feeds:terraform output -raw database_url # secrets.data.DATABASE_URL terraform output -raw storage_connection_string # secrets.data.AZURE_STORAGE_CONNECTION_STRING terraform output storage_account_name # storage.azure.storageAccountName terraform output test_cases_container # storage.testCasesBucket terraform output payloads_container # storage.payloadsBucket terraform output -raw code_executor_function_url # codeExecutor.azure.functionUrl (append /api/execute)
Managed secrets and Redis (recommended)
The module block above provisions both. The Deploy page installs the External Secrets Operator, completes the one federated-credential step, and wires them into the chart:
- Key Vault + External Secrets Operator (
confident_create_key_vault = true): Terraform creates the vault and a managed identity for ESO. - Azure Managed Redis (
confident_managed_redis_enabled = true): managed Redis instead of the in-cluster one, reached over a private endpoint in the subnet you name.terraform output -raw redis_urlgives the value forredis.externalUrl.
Inputs reference
The variables you are most likely to set. For the complete, always-current list, see the module inputs on the Terraform Registry.
Required
| Variable | Description |
|---|---|
confident_resource_group_name | Existing resource group. |
confident_virtual_network_id | Existing VNet id (for the PostgreSQL private DNS link). |
confident_aks_subnet_id | Existing subnet for the AKS nodes. |
confident_database_subnet_id | Existing subnet delegated to Microsoft.DBforPostgreSQL/flexibleServers. |
Commonly set (optional, with production defaults)
| Variable | Default | Description |
|---|---|---|
confident_azure_region | centralus | Region for the cluster and data plane. |
confident_environment / confident_environment_code | stage / s | Naming convention stamped on resources (use prod / p). |
confident_public_aks | false | Expose the cluster API endpoint. |
confident_node_vm_size / confident_node_group_desired_size | Standard_D8s_v5 / 4 | Node pool sizing. |
confident_code_executor_enabled / confident_acr_login_server | true / "" | Code executor Function and the ACR login server holding its image. |
confident_create_key_vault | false | Key Vault and a managed identity for ESO. |
confident_managed_redis_enabled / confident_redis_private_endpoint_subnet_id | false / "" | Azure Managed Redis and its private-endpoint subnet. |
Next step
Deploy with Helm
Install the app with the Terraform outputs and expose it over HTTPS.
Last updated on