- Infrastructure: Terraform provisions AKS, Postgres, Redis, Blob Storage, Key Vault, cert-manager, KEDA, and ingress.
- Application: Helm installs the LangSmith chart against the cluster.
These pages follow the module’s
v0.17.* release tags, which deploy the LangSmith Helm chart 0.17 line. In a module tag, the first two numbers name the chart line and the last number is the module revision, so v0.17.4 still deploys the newest 0.17 chart patch. The v0.16.* tags deploy chart 0.16. They have no LLM Gateway or SSO flags and federate 8 Workload Identity ServiceAccounts instead of 10. From v0.16.56, they deploy SmithDB only with langsmith_helm_chart_version set to ~0.17.0. A deployment that has run chart 0.17 cannot return to 0.16.Prerequisites
Required tools
aks_private_cluster_enabled = true, run Terraform and the make targets from a host with a network path to the API server’s private endpoint, such as a jump host in the cluster VNet or a peered network, with DNS that resolves the private zone. With keyvault_private_endpoint_enabled = true, make apply, make seed-secrets, and make k8s-secrets need a host that resolves the vault’s private endpoint. See Key Vault variables.
Required Azure RBAC
The identity running Terraform needs the following roles on the subscription:Owner includes both. Contributor alone is insufficient because it cannot create role assignments.
A user-assigned control-plane identity (aks_control_plane_identity = "user") and private DNS zones you supply need further grants, listed in PERMISSIONS.md.
Authenticate
dns_label (Azure subdomain, no DNS setup needed) or a custom langsmith_domain.
Quickstart
For the fastest path from zero to a running LangSmith instance:make init, run the rest of steps 5 through 7 in one shot:
make deploy-all stops at each make apply stage prompt. To skip the prompts, run make deploy-all ARGS="-auto-approve". The make seed-secrets step also prompts for the initial admin password, so export LANGSMITH_ADMIN_PASSWORD for an unattended run.
Provision infrastructure
Terraform provisions the following Azure resources:Clone and configure
Clone the modules and check out the newestv0.17.* release tag:
v0.17.* with v0.16.*.
All subsequent commands run from modules/azure/. Run make help for the full target list.
Generate terraform.tfvars with the interactive wizard:
environment defaults to name_prefix. Set it only to tag resources with a different value.
For all variables, see the Azure variables reference.
Bootstrap secrets
setup-env.sh writes infra/secrets.auto.tfvars (gitignored, chmod 600). Terraform picks this file up automatically; no shell exports needed.
- First run: Prompts for the PostgreSQL admin password (press Enter to generate one), the LangSmith license key, and the admin email.
- Subsequent runs: Each prompt offers the previous value as its default. To skip a prompt, set
LANGSMITH_PG_PASSWORD,LANGSMITH_LICENSE_KEY, orLANGSMITH_ADMIN_EMAILin the environment.
make seed-secrets writes them to Key Vault after make apply.
Preflight
terraform.tfvars and secrets.auto.tfvars exist, and that terraform, kubectl, and helm are on PATH.
The subscription must register 11 resource providers: Microsoft.ContainerService, Microsoft.DBforPostgreSQL, Microsoft.Cache, Microsoft.KeyVault, Microsoft.Storage, Microsoft.Network, Microsoft.Compute, Microsoft.Authorization, Microsoft.ManagedIdentity, Microsoft.OperationalInsights, and Microsoft.Insights.
Apply
make init runs terraform init in infra/, which downloads the providers, including AzureRM, and initializes the backend. Run it once per clone. After you check out a new module tag, run make init ARGS=-upgrade.
make apply runs in three stages: Azure infrastructure including AKS → Kubernetes bootstrap (namespace, secrets, cert-manager, KEDA) → remaining resources such as the DNS zone and WAF. Each stage prompts for confirmation. To skip all three prompts, run make apply ARGS="-auto-approve".Cluster credentials and Kubernetes Secrets
Aftermake apply completes, seed the application secrets into Key Vault, get cluster credentials, and push secrets into the cluster:
make seed-secrets prompts for the LangSmith admin password, or reads LANGSMITH_ADMIN_PASSWORD. It generates the API key salt, the JWT secret, and four Fernet encryption keys. It writes only the secrets that are missing, so it is safe to re-run.
make k8s-secrets reads 8 secrets from Key Vault, plus the three langsmith-oauth-* secrets when they exist, and creates or updates langsmith-config-secret. It is safe to re-run.
On a cluster with Entra ID integration, make kubeconfig converts the context to sign in through kubelogin as your az identity.
Verify infrastructure
Deploy LangSmith
make init-values generates the Helm values, and make deploy installs the LangSmith Helm chart. Use the same two commands for first-time deploys and day-2 re-deploys.
Deploy with Helm
Generate Helm values
make init-values reads terraform output and terraform.tfvars and generates helm/values/values-overrides.yaml with all fields populated:
config.hostname, your FQDN (fromdns_labelorlangsmith_domain).config.initialOrgAdminEmail, the first org admin account.config.existingSecretName: langsmith-config-secret, secrets reference.config.blobStorage, storage account name + container + Workload Identity client ID.- Workload Identity annotations for 8 ServiceAccounts (backend, platform-backend, queue, ingest-queue, host-backend, listener, fleet-tool-server, fleet-trigger-server).
- Ingress + TLS block: the
langsmith-tlssecret name forletsencrypt,dns01, andexisting, plus the cert-manager annotation forletsencryptanddns01. Withenvoy-gateway, the chart creates Gateway API routes instead of an Ingress. - Postgres and Redis external secret references (when
postgres_source = "external"/redis_source = "external"). insights.enabledandpolly.enabled, set fromenable_insightsandenable_polly.
clickhouse_source = "external", make init-values also prompts for the ClickHouse connection details and creates the langsmith-clickhouse secret.
make init-values also writes the sizing overlay and any enabled add-on overlays into helm/values/. It copies most of them from helm/values/examples/ and generates the Insights, LLM Gateway, and PII overlays.
Deploy
make deploy does the following:
- Validates
values-overrides.yamlexists and was generated from the currentterraform.tfvars. - Applies
dns_labelto the public IP fornginx,istio, andistio-addonby annotating the LoadBalancer service withservice.beta.kubernetes.io/azure-dns-label-name. - Creates the
letsencrypt-prodcert-managerClusterIssueriftls_certificate_sourceisletsencryptordns01(idempotent). Forexisting, checks that thelangsmith-tlsSecret exists with typekubernetes.io/tls. - Verifies
langsmith-config-secretexists; auto-creates from Key Vault if it is missing. With external ClickHouse, checks thelangsmith-clickhousesecret. - Validates the add-on flags. Agent Builder and Fleet need
enable_deployments = true, Fleet needs external PostgreSQL, and the two cannot run together. - Builds and logs the values chain, and rejects values files still on the chart 0.15 schema.
- Auto-recovers any stuck
pending-upgradeHelm release before proceeding. - For
envoy-gateway, creates theEnvoyProxy(which carries thedns_label),GatewayClass, andlangsmith-gatewayGateway. - Runs
helm upgrade --install langsmith langchain/langsmith --timeout 20m. The long timeout covers the post-install migration Job, which takes up to 5 minutes on first install. The chart version is~0.17.0, the newest 0.17 patch, unlesslangsmith_helm_chart_versionor theCHART_VERSIONenvironment variable names a 0.17 patch. The script rejects any other chart line. - Annotates the
langsmith-ksaServiceAccount with the Workload Identity client ID. - With
enable_llm_gateway = trueandingress_controllerset tonginxoragic, applies the<release>-llm-gatewayIngress for/gateway/, where<release>is the chart fullname (langsmithby default), with a 900-second timeout. With the gateway off, it removes a leftover one.
kubectl get pods -n langsmith -w in a second terminal.
Verify the deployment
https://<HOSTNAME> and log in with the admin email and password from Key Vault:
Values chain
make deploy applies Helm values files in this order (last file wins on conflicts):
helm/values/, values-overrides.yaml and the langsmith-values-*.yaml overlays, are gitignored because they contain live secrets. make init-values writes them, copying most overlays from helm/values/examples/. make clean also deletes the committed values.yaml, and git checkout -- helm/values/values.yaml restores it.
Day-2 operations
Upgrade from chart 0.16
To move a deployment from chart 0.16 to 0.17:-
Check out the newest
v0.17.*module tag: -
Run
make init ARGS=-upgradeto update the providers and modules for the new tag. -
Check that
infra/variables.tfon the new tag declares every variable that yourterraform.tfvarssets. -
If
terraform.tfvarssetslangsmith_helm_chart_versionto a 0.16 version, clear it or set a 0.17 version, and rununset CHART_VERSIONif your shell sets it. On a 0.16 value,deploy.shexits withdoes not resolve to the chart 0.17 line. -
Run
make apply. It adds the two LLM Gateway federated credentials. -
Run
make init-valuesto regenerate the values files in the chart 0.17 shape. -
Run
make deploy.
engine.usageSigningSecret (at least 32 characters), or an engine_usage_signing_secret key in the Secret that config.existingSecretName names.
Beyond the two federated credentials, the upgrade on Azure only moves the chart pin. An installation still on chart 0.15 must first follow MIGRATION-0.15-to-0.16.md. For the full list of chart changes, see MIGRATION-0.16-to-0.17.md.
Enable add-ons
Each add-on is gated by a flag ininfra/terraform.tfvars. Set the flag, re-run make init-values to regenerate values, then re-run make deploy.
LangSmith Deployment
Enables LangSmith Deployment, which lets you deploy and manage agents as API servers directly from the LangSmith UI. This adds three new pods.Scale the node pool first
Before enabling, bumpdefault_node_pool_min_count to at least 5. The operator spawns agent deployment pods on demand and needs node headroom:
Pending indefinitely.
Apply, regenerate values, deploy
make init-values appends the LangSmith Deployment add-on overlay (langsmith-values-agent-deploys.yaml) to the values chain. It automatically injects:
https:// protocol in url, operator-deployed agents stay stuck in DEPLOYING. make init-values overwrites these values on every run, so do not edit them in the overlay file.
Verify
langsmith-host-backend, langsmith-listener, and langsmith-operator all Running. Total pod count: ~20 Running + 3 Completed jobs.
KEDA is already installed alongside infrastructure. With enable_deployments = true, the operator creates KEDA ScaledObject resources for each agent deployment’s worker queue. Worker pods scale down to zero when idle and scale up based on Redis queue depth.
Fleet
Fleet is the supported successor to Agent Builder. Unlike the other add-on flags,enable_fleet also drives Terraform. make apply creates a dedicated langsmith_fleet database on the external PostgreSQL server and the langsmith-fleet-postgres Kubernetes secret.
make init-values and make deploy enforce three requirements:
enable_deployments = truepostgres_source = "external"enable_agent_builder = false
langsmith-config-secret. Its Redis runs in the cluster as a chart-managed pod, because Azure Managed Redis cannot isolate Fleet in its own logical database.
The langsmith-fleet-tool-server and langsmith-fleet-trigger-server ServiceAccounts need Workload Identity to access Azure Blob Storage. Their federated credentials are pre-registered in infra/modules/k8s-cluster/main.tf; no additional setup is needed.
Verify:
Agent Builder
enable_agent_builder is the legacy path. On chart 0.16 and later, it adds the Agent Builder UI navigation item and the Fleet tool and trigger servers, but no agent runtime. Use Fleet instead. The two flags are mutually exclusive, and make deploy stops with an error when both are set, or when enable_deployments is off.
Insights and Polly
Two features, independent of each other; enable either one without the other. Polly runs on LangSmith Deployment, so setenable_deployments = true with it. The deploy scripts do not check this.
- Insights: AI-powered trace analytics. Surfaces patterns and anomalies in LangSmith traces. Runs as static
standalone-insightsapi-server and queue pods. The overlay sets top-levelinsights.enabled: true. - Polly: AI-powered evaluation and monitoring agent. Runs as static
standalone-pollyapi-server and queue pods. The overlay sets top-levelpolly.enabled: true.
terraform apply needed; run make init-values && make deploy.
values-overrides.yaml, driven by clickhouse_source in terraform.tfvars.
Verify:
langsmith-polly-config ConfigMap existed. Run kubectl rollout restart deployment langsmith-frontend -n langsmith.
SmithDB
enable_smithdb = true provisions the Azure infrastructure SmithDB needs: a dedicated PostgreSQL 18 metastore, a Blob container, a Workload Identity, and Premium SSD v2 cache volumes. It also requires a non-empty availability_zones, because Premium SSD v2 attaches only to zonal VMs in most regions. AKS applies zones only at cluster creation, so set availability_zones in the first make apply if you plan to use SmithDB. On a cluster created without zones, adding them later passes the plan, but the module ignores zone changes on the existing node pool: the nodes stay non-zonal, and every plan prints a zone drift warning.
SMITHDB.md in the Azure module repo.
LLM Gateway
enable_llm_gateway = true deploys the LLM Gateway, which lets one LangSmith API key call models across the providers your organization configures. The LLM Gateway is in beta and requires chart 0.17.
After the deploy, an organization admin turns the gateway on for workspaces, adds provider secrets, and grants access. For more information, see LLM Gateway admin setup.
- Workload Identity: Terraform federates the
<release>-agent-gatewayand<release>-presidio-analyzerServiceAccounts whether or not the flag is set, so a cluster applied from av0.17.*tag needs nomake apply. On a cluster last applied from an older tag, runmake applyonce first. - Timeouts: Model calls can run for up to 900 seconds. With
ingress_controllerset tonginxoragic,make deploygives/gateway/its own Ingress with a 900-second timeout, andmake uninstallremoves it. Istio sets no request timeout by default. Withenvoy-gatewayornone,make init-valuesprints a warning, and you raise the timeout on that controller yourself. - PII redaction:
enable_gateway_pii_redaction = trueadds the Presidio analyzer and turns redaction on for new organizations. It requiresenable_llm_gateway = true. The analyzer image,mcr.microsoft.com/presidio-analyzer, comes from Microsoft’s registry, so a private registry mirror must include it under that path.
SSO with OIDC
enable_sso_oidc = true switches LangSmith login from basic auth to SSO through a standard OIDC provider, such as Microsoft Entra ID, Okta, Auth0, or Google Workspace.
To enable SSO:
-
Store the OIDC client credentials in Key Vault:
Set the client secret through
make keyvault, which reads the value without echoing it. Passed on the command line, the secret shows in the process list and in your shell history. For Entra ID, the issuer URL ishttps://login.microsoftonline.com/<tenant-id>/v2.0. The/v2.0suffix is required. -
Set
enable_sso_oidc = trueininfra/terraform.tfvars. -
Re-create the Kubernetes secret, regenerate the values, and deploy:
make init-values stops with an error when any of the three Key Vault secrets is missing.
Add-on summary
Ingress controllers
Setingress_controller in terraform.tfvars before make apply. For the full TLS compatibility matrix, see INGRESS_CONTROLLERS.md in the Azure module repo.
DNS and TLS
dns_label gives you a free Azure subdomain, <label>.<region>.cloudapp.azure.com, with no domain registration or DNS zone needed. deploy.sh annotates the correct LoadBalancer service automatically. For envoy-gateway, it sets the label on the EnvoyProxy resource instead.
The default tls_certificate_source is letsencrypt.
HTTP only (demo or dev):
make deploy, create a kubernetes.io/tls Secret named langsmith-tls in the langsmith namespace. Put the leaf certificate first, then the intermediates. deploy.sh stops if the Secret is missing or has the wrong type. Renewal is your responsibility.
langsmith_custom_ca_secret_name to a Secret in the langsmith namespace that holds the CA bundle. The bundle key defaults to ca.crt; override it with langsmith_custom_ca_secret_key.
make applycreates the Azure DNS zone and outputs 4 nameservers.- At your registrar, add NS records for the subdomain pointing to those 4 nameservers. Use NS delegation, not a CNAME: cert-manager writes the DNS-01 TXT record to the zone, so Azure DNS must be authoritative for the subdomain.
- Verify:
dig NS langsmith.mycompany.com @8.8.8.8. make deployissues the cert via DNS-01 automatically (Workload Identity writes the TXT record to Azure DNS).- Get the LB IP, add
ingress_ip = "<ip>"toterraform.tfvars, thenmake apply(creates the A record). Forenvoy-gateway, runkubectl get svc -n envoy-gateway-system -l gateway.envoyproxy.io/owning-gateway-name=langsmith-gateway. Fornginx, runkubectl get svc -n ingress-nginx. make statusshows exactly what NS and A records to add at each stage.
Next steps
- Reference the Azure variables and the quick reference.
- Review the Azure architecture for module structure, traffic flow, and Workload Identity.
- When something breaks, check the Azure troubleshooting guide.
- Enable agent deployment in the UI with LangSmith Deployment.
Connect these docs to your agent of choice via MCP for real-time answers.

