make apply.
Use this page as a reference while planning a rollout or troubleshooting an existing one. It covers:
- Platform layers and deployment tiers (light versus production).
- Application deployment paths (Helm versus Terraform).
- Networking, Workload Identity, and secret flow.
- Add-ons: LangSmith Deployment, Agent Builder, Insights, and Polly.
- Ingress controllers, resource sizing, and optional modules.
Platform layers
LangSmith on Azure deploys in stages. Each stage adds a capability layer on top of the previous. All layers share the same AKS cluster andlangsmith namespace.

Application deployment paths
The Terraform path uses the
app/ module. make init-app calls app/scripts/pull-infra-outputs.sh to read all infra outputs and write them into app/infra.auto.tfvars.json.
Deployment tiers
Light deploy (all in-cluster)
terraform.tfvars:
BUILDING_LIGHT_LANGSMITH.md in the Azure module repo.
Production (external managed services)
Networking
Light deploy
Production
Application core services
SmithDB is LangSmith’s purpose-built observability backend, available for Self-hosted starting with self-hosted version 0.16.0 (see deployment support). These Terraform modules provision ClickHouse, so the guidance in the previous sections applies to current deployments.
One-time jobs
LangSmith Deployment add-on
Agent Builder add-on
Insights and Polly add-on
Insights/Clio: No static pods. Deploys lazily as a dynamic LangGraph deployment via the operator on first UI invocation. Readsinsights_encryption_key from langsmith-config-secret. Never rotate this key: it permanently breaks existing Insights data.
Polly: Runs as a dynamic LangGraph deployment, operator-managed. Reads polly_encryption_key from langsmith-config-secret. Same rotation warning as Insights.
Azure managed services
Whenpostgres_source = "external" and redis_source = "external" (the recommended production setting), Terraform provisions:
Azure DB for PostgreSQL Flexible Server
- Holds orgs, users, projects, API keys, settings.
- PostgreSQL ≥ 14 required. The
postgresmodule setspostgres_versionto14by default. - Extensions enabled automatically by the
postgresmodule:btree_gin,btree_gist,pgcrypto,citext,pg_trgm. - Private VNet only (
subnet-postgres), SSL port 5432. - Secret:
langsmith-postgres-secret, created by thek8s-bootstrapTerraform module.
Azure Managed Redis
- Trace ingestion queue, pub/sub, short-lived cache.
- Azure Managed Redis manages the engine version; there is no version variable to set.
- Each LangSmith installation must use its own dedicated Redis. Shared instances cause deployment tasks to route incorrectly.
- Private VNet only (
subnet-redis), TLS port 10000. - Secret:
langsmith-redis-secret, created by thek8s-bootstrapTerraform module.
Azure Blob Storage
- Trace payloads: large inputs and outputs, attachments.
- Workload Identity (no static keys) via the
k8s-app-identityManaged Identity. - Always required. Disabling blob storage breaks the cluster on large payloads.
- Prefixes:
ttl_s/(14-day TTL),ttl_l/(400-day TTL).
Azure Key Vault
- Centralized secret store for all LangSmith secrets.
- Secret flow:
az keyvault secret show→kubectl create secret generic langsmith-config-secret.
Workload Identity
Azure AD token exchange happens via the AKS OIDC issuer. Pods access Blob Storage without static keys.modules/k8s-cluster/ alongside the managed identity and OIDC issuer, which avoids circular dependencies and simplifies adding new ServiceAccounts.
Which pods need Workload Identity
Every pod that reads blob storage env vars must have:- A federated credential registered in Terraform (
modules/k8s-cluster/main.tf). - The
azure.workload.identity/use: "true"label on the Deployment. - The
azure.workload.identity/client-idannotation on the ServiceAccount.
All federated credentials are registered in
modules/k8s-cluster/main.tf under service_accounts_for_workload_identity. Adding a new pod that accesses blob storage requires adding its ServiceAccount name to that list and running terraform apply -target=module.aks.
If a pod’s ServiceAccount has no registered federated credential, Azure AD rejects the token exchange and the pod panics on startup:
Secret flow
secrets.auto.tfvars is never committed. Running ./setup-env.sh on any machine restores it: the generated secrets come from Key Vault, and the user-provided secrets are re-prompted unless supplied through the LANGSMITH_* environment variables. Terraform is the sole writer to Key Vault; setup-env.sh only reads from it after the first apply.
Ingress options
Azure Public IP DNS labels (
dns_label) work with all controllers. deploy.sh applies the service.beta.kubernetes.io/azure-dns-label-name annotation to the correct LoadBalancer service based on the chosen controller.
For the full TLS compatibility matrix and per-controller setup, see INGRESS_CONTROLLERS.md in the Azure module repo.
Resource sizing
Four sizing profiles are available.AKS node pools
ClickHouse (when in-cluster) requests 1 to 4 CPU and 2 to 16 GB RAM depending on profile. With LangChain Managed ClickHouse, the
large pool is only needed for LGP operator-spawned agent pods.Optional modules
Each module is count-controlled (0 disabled, 1 enabled). Enable any combination; the core deployment (Passes 1 to 5) works without them.
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

