Running on Azure #
This guide covers running the Temporal operator on Azure: AKS, Azure Database for PostgreSQL Flexible Server, Application Gateway ingress, and passwordless Microsoft Entra authentication.
AKS prerequisites #
- An AKS cluster (
az aks create ...). - The operator installed (see the installation guide).
Persistence: Flexible Server #
Azure Database for PostgreSQL Flexible Server is the recommended SQL backend.
- Create the
temporalandtemporal_visibilitydatabases up front — the operator runssetup-schemabut does not create databases. - Raise
max_connections(~200) to avoid pool exhaustion on smaller SKUs. - TLS is required; set
tls.enabled: trueon each store. Azure chains to a public root, so no CA secret is needed.
Example:
examples/cluster-azure-postgres-flexible.
Exposing the UI with Application Gateway (AGIC) #
Set ui.ingress.ingressClassName: azure-application-gateway and AGIC
annotations.
Example:
examples/cluster-azure-aks-ingress.
Accessing the UI without an ingress #
When the UI is enabled (ui.enabled: true) but no ingress is configured — for
example the standing cluster from make azure-e2e-deploy — reach it with a
port-forward to the operator-generated <cluster>-ui Service (ClusterIP, port
8080):
kubectl -n azure-e2e port-forward svc/azure-e2e-ui 8080:8080
# open http://localhost:8080
Substitute your namespace and <cluster>-ui Service name for other clusters.
Passwordless auth with Microsoft Entra + Workload Identity #
For authenticating clients and the UI to Temporal with Microsoft Entra (JWT + OIDC), see Authentication & Authorization.
Each actor in the system obtains an Entra token through a different mechanism:
| Actor | Token mechanism |
|---|---|
| Temporal server pods | azure-token-refresher sidecar writes a token to a shared emptyDir; Temporal reads it via passwordCommand (podTemplate override) |
| Schema Job | one-shot initContainer writes a token before the schema container starts; schema container reads it via passwordCommand (schemaJob.podTemplate) |
| Operator (probe + schema inspection) | obtains an Entra token natively in-process via the Go Azure Workload Identity SDK — no sidecar; enabled by setting sql.azureWorkloadIdentity: {} on each datastore |
The operator runs on a distroless image with no shell, so it cannot use
passwordCommand. Instead, set sql.azureWorkloadIdentity: {} on each store and
install the operator with Workload Identity enabled so the Go SDK picks up the
projected OIDC token automatically — no token-refresher sidecar on the operator pod.
- Enable the OIDC issuer and Workload Identity on AKS:
az aks update -g <rg> -n <cluster> --enable-oidc-issuer --enable-workload-identity. - Create a managed identity and a federated credential bound to the
temporal-azureServiceAccount (for cluster pods and schema Jobs) and another bound to thetemporal-operator-controller-managerServiceAccount intemporal-system(for the operator’s native in-process token). These can be the same identity or separate ones; each needs a federated credential and a Postgres role. - Enable Entra auth on the Flexible Server and map each identity to a Postgres
role with
pgaadauth_create_principal. - Install the operator with Workload Identity enabled:
helm install temporal-operator oci://ghcr.io/bmorton/charts/temporal-operator --set workloadIdentity.enable=true --set workloadIdentity.clientId=<client-id>. This adds the WI label and SA annotation to the operator pod; no sidecar is added to the operator.
Full passwordless support (operator probe + schema Job + server pods) is available as of this release. Issue #47 tracked this work. The operator’s own native token currently supports Azure Workload Identity only; #84 tracks generic / multi-provider support (e.g. AWS RDS IAM).
Example:
examples/cluster-azure-workload-identity.