Agent Observability Platform: Prerequisites (Azure)
What you need before deploying the Agent Observability data platform on Azure
What you need before deploying the Agent Observability data platform on Azure.
This page walks through everything you need before running the installation: the right tooling, an Azure subscription with sufficient permissions, a deployment path, a DNS zone, and the platform artifacts. Work through the steps in order, then run the preflight check to confirm you are ready.
1. Install the required tooling
Install the following on the machine you will run Terraform from:
| Tool | Version | Used for |
|---|---|---|
| Terraform | >= 1.3 | Provisioning the platform |
Azure CLI (az) | latest | Authenticating to Azure and retrieving outputs β also invoked by the module during terraform apply |
| kubelogin | latest | Entra ID authentication to the AKS API β required by the kubernetes/helm providers and kubectl |
| kubectl | latest | Verifying the cluster after deployment β also invoked by the module during terraform apply |
| Helm | 3.x | Only for the self-managed Helm path |
Sign in with az login and select the target subscription before continuing. The module's provisioners shell out to az, kubelogin, and kubectl during terraform apply, so all three must be on the PATH of the machine running Terraform β not just installed for interactive use.
2. Prepare your Azure subscription
You deploy into your own Azure subscription. The principal running terraform apply needs two kinds of access on the target scope:
- Resource management β creating and managing the resource group, VNet, AKS cluster, Key Vault, managed identities, DNS records, and the Foundry account (Contributor-level access).
- Authorization writes β
Microsoft.Authorization/roleDefinitions/writeandMicrosoft.Authorization/roleAssignments/write. The module creates a custom least-privilege role definition for the Claude evaluation backend and many role assignments (Workload Identities, Key Vault RBAC, DNS Zone Contributor, and the deployer's own AKS RBAC Cluster Admin grant).
In practice that means Owner, or Contributor plus User Access Administrator, on the subscription or target scope. Contributor alone β or Contributor plus "Role Based Access Control Administrator" β is not enough, because neither can write role definitions.
The principal that runs terraform apply is granted cluster-administrator access on the AKS cluster automatically (an "Azure Kubernetes Service RBAC Cluster Admin" role assignment), so the same credentials you deploy with can administer the cluster afterward.
The platform artifacts are public (Terraform Registry and Docker Hub), so no registry credentials are needed β only outbound access to Docker Hub: the helm provider pulls the ao-data-platform chart during apply, and the AKS nodes pull the ao-llm-worker image at runtime.
Resource providers
Make sure the following resource providers are registered in the subscription (registration is idempotent β running it again is harmless):
az provider register --namespace Microsoft.ContainerService
az provider register --namespace Microsoft.Network
az provider register --namespace Microsoft.KeyVault
az provider register --namespace Microsoft.ManagedIdentity
az provider register --namespace Microsoft.CognitiveServicesNo preview-feature registrations are required β the managed Gateway API and application-routing Istio add-ons the platform uses are generally available, and the module enables them declaratively during terraform apply on clusters it creates.
Azure services the deploy uses
The table below lists the Azure services and representative operations the deploy exercises, by category. Treat it as the breadth of access the deploying principal needs, not a hand-minimized least-privilege policy.
| Category | Provider | Representative operations |
|---|---|---|
| VNet & networking (new-cluster path) | Microsoft.Network | Create/read/delete on virtual networks, subnets, NAT gateway, public IP; record sets in your existing DNS zone |
| AKS cluster & node pools | Microsoft.ContainerService | Create/read/update managed clusters and agent pools, including the Gateway API / app-routing-Istio ingress-profile update |
| Managed identities | Microsoft.ManagedIdentity | Create user-assigned identities and federated identity credentials (Workload Identity) |
| Key Vault | Microsoft.KeyVault | Create the vault, write/read secrets, manage the key used for AKS etcd encryption |
| Foundry (Claude evaluation) | Microsoft.CognitiveServices | Create the AIServices account, project, and model deployments |
| Authorization | Microsoft.Authorization | roleDefinitions/write (custom inference role), roleAssignments/write (identity, Key Vault, DNS, and cluster-admin grants) |
3. Choose your deployment path
The Terraform module supports two paths. Decide which applies before configuring it:
| Path | When to use | Additional inputs |
|---|---|---|
| New cluster | You want Terraform to create the VNet and AKS cluster. | clickhouse_zones and keeper_zones β a module-created cluster always runs the zoned ClickHouse/Keeper topology, so both are required (a single zone each is the low-cost dev floor; see High availability). Everything else uses defaults (cluster name monte-carlo, resource group ao-data-platform). Override networking.vnet_address_space β the default 10.18.0.0/16 is a placeholder; pick a range that doesn't collide with your networks. |
| Existing cluster | You already run an AKS cluster and want to deploy the platform into it. | cluster.create = false, cluster.existing_cluster_name, cluster.existing_resource_group_name, and networking.existing_vnet_id / networking.existing_subnet_ids (entry [0] is the AKS node subnet). location must match the cluster's region. |
Existing cluster β four things to check:
OIDC issuer and Workload Identity must be enabled on the cluster β the platform's identities (External Secrets, external-dns, cert-manager, LLM worker) federate to Kubernetes ServiceAccounts through it.
Gateway API and application-routing Istio add-ons must be enabled out-of-band (the module enables them only on clusters it creates, and verifies them at plan time on existing clusters):
az aks update -g <resource-group> -n <cluster> --enable-gateway-api az aks update -g <resource-group> -n <cluster> --enable-app-routing-istioExisting controllers. If cert-manager, the External Secrets Operator, or external-dns are already installed, set the matching
helm.install_*flag tofalseto skip reinstalling them (see Installation).HA node pools. The module creates the per-zone ClickHouse and Keeper node pools only on the new-cluster path. On an existing cluster you attach them yourself β see High availability.
Quotas to verify
- vCPU quota for the VM families in your region: the main pool defaults to
Standard_D4s_v5Γ 2 (autoscaling up to 10), each dedicated ClickHouse node isStandard_E8s_v5, and each Keeper voter isStandard_D2as_v4. - Claude tokens-per-minute quota: the module provisions three Claude model deployments by default, each at capacity
100(= 100,000 TPM,GlobalStandard). If that exceeds the Claude quota granted in your subscription, scope it down withhelm.llm_worker.foundry.deployments/default_capacityβ see the Configuration reference. - Premium SSD v2 availability varies by region and zone β verify the target region/zone supports it, or point
clickhouse_storage_classat a different StorageClass (see Storage). - Kubernetes version: the module pins
kubernetes_version = "1.35"by default β confirm it is available in your region withaz aks get-versions --location <region>.
4. Configure domains and DNS
The OpenTelemetry Collector and ClickHouse are exposed as two hostnames on a single managed Gateway backed by an internal load balancer, with publicly-trusted TLS. Decide on:
- A domain for the OpenTelemetry Collector endpoint (e.g.
otel.acme.com) β passed asotel_collector_domain - A domain for the ClickHouse endpoint (e.g.
clickhouse.acme.com) β passed asclickhouse_domain - An existing Azure DNS zone covering those domains β passed as
dns_zone(e.g.acme.com), plusdns_zone_resource_group_namewhen the zone lives in a different resource group than the platform (the common case)
The DNS zone is required whenever the module deploys the chart β there is no manual-DNS or self-signed fallback. cert-manager issues publicly-trusted Let's Encrypt certificates via DNS-01 validation against the zone, and external-dns publishes the two hostnames automatically; the module grants both identities DNS Zone Contributor scoped to the zone. "Publicly trusted" describes the certificate chain (clients need no private CA) β the endpoints themselves stay on a private IP, reached over VNet, peering, or VPN connectivity.
Optionally set gateway.letsencrypt_email as the ACME contact address β omit it for a contactless account (certificates still auto-renew).
5. Get the platform artifacts
All three artifacts are public β no Monte Carlo-issued credentials or registry login are required:
| Artifact | Location | Version |
|---|---|---|
| Terraform module | Terraform Registry β monte-carlo-data/ao-data-platform/azurerm | ~> 1.0 |
ao-data-platform Helm chart | Docker Hub (OCI) β oci://registry-1.docker.io/montecarlodata/ao-data-platform | 4.0.0 |
ao-llm-worker image | Docker Hub β montecarlodata/ao-llm-worker | 1.1.0-azure |
You don't fetch these by hand: terraform init pulls the module from the Registry, the helm provider pulls the chart during terraform apply, and the AKS nodes pull the image at runtime. You set the chart registry and version (and pin the image tag) as module inputs on the installation page.
The module requires
ao-data-platformchart version 4.0.0 or later β older chart versions don't carry the Azure Gateway and Foundry configuration the module renders.
6. Run the preflight check
Confirm your environment is ready. Each command below should succeed before you proceed to installation:
# Terraform is installed and >= 1.3
terraform version
# Azure credentials resolve to the target subscription
az account show
# kubectl and kubelogin are installed (server check comes after the cluster exists)
kubectl version --client
kubelogin --version
# The DNS zone resolves in its resource group
az network dns zone show --resource-group <dns_zone_resource_group_name> --name <dns_zone>
# The pinned Kubernetes version is available in the region
az aks get-versions --location <region> --output table
# Optional: confirm you can reach the public chart on Docker Hub (no login required)
helm pull oci://registry-1.docker.io/montecarlodata/ao-data-platform --version 4.0.0If az account show returns the wrong subscription, or terraform version reports below 1.3, fix those before continuing.
Next steps
Continue to Installation.
Updated 1 day ago
