Overview
This guide covers Azure-specific integration for CrewAI Platform deployments on Azure Kubernetes Service (AKS). It focuses on how CrewAI uses Azure services and the platform-specific configuration required, rather than general Azure setup.This guide assumes you have:
- An AKS cluster running Kubernetes 1.27+ with at least 3 nodes (4 vCPU / 8 GB RAM minimum per node)
- Azure CLI installed and authenticated (
az login) - Helm 3.10+ and kubectl configured for your cluster
- Basic familiarity with Azure services (Azure Database for PostgreSQL, Azure Blob Storage, ACR)
Prerequisites
Before configuring CrewAI Platform, ensure these Azure components are in place: CrewAI Platform supports AMD64 (x86_64) Kubernetes worker nodes. ARM64 (aarch64) worker nodes are not currently supported. For full platform requirements, see the Requirements Guide.Required Azure Infrastructure
Azure Database for PostgreSQL Flexible Server
CrewAI Platform requires PostgreSQL 16 for production deployments. This section covers Azure Database for PostgreSQL Flexible Server requirements.Instance Sizing
Minimum recommended specifications based on CrewAI workload characteristics:Memory-optimized SKUs (
Standard_E family) provide better performance for CrewAI’s connection-heavy Rails architecture. For production workloads, enable high availability with a standby replica.Create the PostgreSQL Instance
Network Connectivity
CrewAI pods must reach your PostgreSQL instance. Two options: Option 1: Private Access via VNet Integration (Recommended)- Deploy the Flexible Server into the same VNet as your AKS cluster using a delegated subnet
- No public internet exposure
- PostgreSQL (5432) is reachable only from within the VNet
- Enable public access and restrict by AKS outbound IP ranges
- Requires SSL/TLS enforcement
Database Setup
Azure Database for PostgreSQL only lets you create extensions that are on the server’sazure.extensions allow-list. Allow the extensions the platform uses before you install:
The value replaces the whole allow-list. If the server already allows other extensions, keep them in the list.
Using a Dedicated Application Role
The examples above connect as the server’s admin user (crewai). If the platform connects with a dedicated role that is not the server admin, that role needs three more things:
CREATEDB. The setup job runsrails db:createon every install, even when the databases already exist, and fails without this attribute.- Ownership of the
publicschema in each of the four databases. On Azure Database for PostgreSQL, thepublicschema of a new database belongs toazure_pg_admin, so migrations fail withpermission denied for schema public. - The
vectorextension, created by the admin.vectoris not a trusted extension, so only members ofazure_pg_admincan create it, even when it is on the allow-list. On Azure this check applies even when the extension already exists, so the platform’s role cannot enable it during setup: the column that uses it is skipped and no error is shown. The admin creates the extension, and the platform’s role then adds the column after the first install.
<app_role> with the platform’s role:
envVars.DB_USER to that role.
After the first install, connect to crewai_plus_production as the platform’s role and add the column that uses vector. The statements are idempotent, so you can also run them on an existing installation:
Helm Configuration
Azure Blob Storage for Object Storage
CrewAI Platform uses Azure Blob Storage for storing crew artifacts, tool outputs, and user uploads whenSTORAGE_SERVICE is set to "microsoft".
Create Storage Account and Container
The name you choose for the container (e.g.,
crewai-storage) becomes the value for AZURE_CONTAINER_NAME in your Helm values, and AZURE_STORAGE_ACCOUNT_NAME is the storage account name. If AZURE_CONTAINER_NAME is empty, CrewAI Platform uses a container named crewai-plus-production, which must then exist in the account.Storage Authentication Options
CrewAI supports two authentication methods for Azure Blob Storage. Choose based on your security requirements:Option 1: Workload Identity (Recommended)
Best for: Production AKS deployments, highest security. No long-lived credentials stored in Kubernetes secrets. Azure Workload Identity binds an AKS pod’s service account to an Azure Managed Identity (or App Registration) via federated credential trust — no static keys required. Setup Steps:- Enable the AKS OIDC Issuer and Workload Identity:
- Create a User-Assigned Managed Identity:
- Grant Storage Blob Data Contributor role to the Managed Identity:
- Create Federated Credential for AKS:
crewai-sa service account name is the chart default when rbac.create: true.
When
rbac.create: true (the default), the chart automatically creates a ServiceAccount named crewai-sa. Setting serviceAccount.azureWorkloadIdentity: true adds the azure.workload.identity/use: "true" label to platform pods, enabling the AKS Workload Identity webhook to inject federated credentials. The federated credential must reference this exact ServiceAccount name and namespace.Option 2: Storage Access Key
Best for: Development environments or deployments outside AKS where managed identity is not available.AZURE_CONTAINER_NAME is the name of the blob container within the storage account (e.g.,
crewai-storage), not the storage account name itself. It must match the container you created in Azure. If it is empty, the platform uses a container named crewai-plus-production.Azure Container Registry (ACR) for Crew Images
CrewAI Platform requires a writable container registry to build and push crew automation container images. When users create and deploy crews, CrewAI builds container images and pushes them to ACR.ACR Repository Requirements
Create ACR and Repository
CREW_IMAGE_REGISTRY_OVERRIDE values:
crewairegistry.azurecr.io— appends/crewai-enterpriseautomaticallycrewairegistry.azurecr.io/production— appends/crewai-enterpriseautomaticallycrewairegistry.azurecr.io/my-org— appends/crewai-enterpriseautomatically
ACR Authentication with Workload Identity
CrewAI pods require ACR push and pull permissions for building and deploying crew images. Grant AcrPush to the Managed Identity (uses the same identity created for Blob Storage):The crews namespace federated credential below is needed only with the BuildKit provider (
envVars.PROVIDER: BUILDKIT_KUBERNETES). With the default no-build provider (KUBERNETES_V3), crews are not built in the cluster and do not push images to ACR. If your crew code calls Azure APIs with Workload Identity on the no-build provider, contact CrewAI Support.crewai-crews namespace (build pods that push images), you also need a federated credential for that namespace’s default service account. Create this after the first helm install, which automatically creates the crewai-crews namespace:
ArgoCD users: This step requires a two-Application pattern because the
crewai-crews namespace does not exist until after the first sync completes. See the ArgoCD Deployment Guide.ACR Authentication with Static Credentials
For environments where managed identity is not available, you can use an ACR service principal with static credentials:Helm Configuration for ACR
Combined Workload Identity Setup (Storage + ACR)
When using Workload Identity for both Blob Storage and ACR (recommended), a single managed identity covers both:Verifying ACR Access
Test ACR authentication from CrewAI pods:Gateway API
CrewAI Platform exposes the web application through the Kubernetes Gateway API. On AKS you can use either of two implementations, and you choose one withgateway.gatewayClassName:
Both implementations terminate TLS at the Gateway and forward plain HTTP to the web pods, so set
web.enableSslFromPuma: false. Both health-check the web pods through their readiness probe, so no extra health check resource is needed.
Enable the Managed Gateway API
Both options use the Gateway API CRDs that AKS installs and manages:Option 1: App Routing
Enable the App Routing implementation of the Gateway API:A record for your hostname at the Gateway address:
Preserve the Client IP
By default, the Load Balancer Service that App Routing creates for the Gateway usesexternalTrafficPolicy: Cluster, so the platform sees a node IP instead of the client IP. The platform uses the client IP for rate limiting and audit records, so preserve it.
Create a ConfigMap in the release namespace that sets externalTrafficPolicy: Local on the Gateway Service. Because App Routing points the Azure Load Balancer health probe at a fixed port by default, the ConfigMap also sets a health check node port and points the probe at it. Choose a port in the node port range (30000-32767) that no other Service uses:
Internal Load Balancer
To expose the Gateway only inside your virtual network, add the Azure annotation to the Gateway Service:Option 2: Application Gateway for Containers
-
Install the ALB Controller with Helm by following the Microsoft quickstart. Because AKS manages the Gateway API CRDs, add
--set albController.installGatewayApiCRDs=falseto thehelm installcommand. Without it, the controller pods fail to start because AKS rejects changes to the managed CRDs. -
Create the Application Gateway for Containers resource. With the deployment managed by the ALB Controller, define an
ApplicationLoadBalancerthat uses a subnet delegated toMicrosoft.ServiceNetworking/trafficControllers(see the Microsoft quickstart): -
Configure the chart to use it:
-
After installation, point a
CNAMErecord for your hostname at the Gateway address:
TLS Certificates
The HTTPS listener reads its certificate from the Kubernetes TLS Secret named incertificateRefs. You can create the Secret yourself:
-
Enable Gateway API support in cert-manager:
-
Create a ClusterIssuer that solves HTTP-01 challenges through the Gateway’s HTTP listener:
-
Annotate the Gateway. cert-manager creates a Certificate for each HTTPS listener that has a
hostnameand acertificateRefsentry:
The HTTP listener must stay reachable from the internet for HTTP-01 challenges. With
gateway.httpsRedirect.enabled: true, every other request on that listener is redirected to HTTPS.Microsoft Entra ID Authentication
CrewAI Platform uses Microsoft Entra ID (formerly Azure Active Directory) for enterprise SSO. Full setup instructions are in the Microsoft Entra ID Guide, but the key Helm values are:Helm Configuration
The callback URL you register in Entra ID must match your application host and use the path
/auth/entra_id/callback. For example: https://crewai.your-company.com/auth/entra_id/callback.Azure Key Vault Integration
Azure Key Vault provides centralized secret management with audit logging for CrewAI Platform. The chart integrates with Key Vault via External Secrets Operator (ESO).Which Secrets to Store
Store in Azure Key Vault (sensitive, need rotation):DB_PASSWORD— Database credentialsSECRET_KEY_BASE— Rails secret keyENTRA_ID_CLIENT_SECRET— Entra ID OAuth secretAZURE_STORAGE_ACCESS_KEY— If using access key auth for storageGITHUB_TOKEN— For private repository access
DB_HOST,DB_PORT,DB_USER,POSTGRES_DB,POSTGRES_CABLE_DBAZURE_STORAGE_ACCOUNT_NAME,AZURE_CONTAINER_NAMEAPPLICATION_HOSTAUTH_PROVIDER,ENTRA_ID_CLIENT_ID,ENTRA_ID_TENANT_ID
Create Key Vault
Grant Key Vault Secrets Officer to Managed Identity
Install External Secrets Operator
Helm Configuration for Key Vault
The chart’ssecretStore block creates a SecretStore resource pointing to Azure Key Vault. Use Workload Identity authentication (recommended) or Service Principal.
Using Workload Identity:
Complete Azure Deployment Example
If using WorkOS authentication, place
WORKOS_API_KEY under envVars: — NOT under secrets:. See the WorkOS SSO guide for the full explanation and the correct YAML placement. This is a known chart limitation.Troubleshooting Azure-Specific Issues
Pods Fail to Pull Images from images.crewai.com
Symptoms: Platform pods show ImagePullBackOff or ErrImagePull on images from images.crewai.com
First check — verify global.imageRegistry is not set to ACR: Setting global.imageRegistry to your ACR host redirects all platform image pulls away from images.crewai.com. Check your values file for this pattern and remove it:
global.imageRegistrywas set to the ACR hostname — this redirects all platform image pulls away fromimages.crewai.com
global.imageRegistry from your values. Only CREW_IMAGE_REGISTRY_OVERRIDE should reference ACR.
Workload Identity Not Working — Access Denied to Blob Storage
Symptoms: Logs showAuthorizationPermissionMismatch or 403 errors for Blob Storage operations
Verify the OIDC issuer and federated credential:
azure.workload.identity/use: "true" label on pods, enabled via serviceAccount.azureWorkloadIdentity: true):
PostgreSQL Connection Timeout
Symptoms: Pods showcould not connect to server: Connection timed out
Check VNet connectivity:
ACR Push Fails — Unauthorized
Symptoms: BuildKit logs showunauthorized: authentication required when pushing crew images
Verify the AcrPush role assignment:
Key Vault ExternalSecret Sync Errors
Symptoms: ExternalSecret showsSecretSyncedError
ServiceAccount Mismatch with Workload Identity
Symptoms: Pods showAuthorizationFailed despite correct Azure role assignments
Common causes:
- Wrong ServiceAccount name in federated credential — The
--subjectin the federated credential must exactly match the namespace and ServiceAccount name used by pods - Missing
azure.workload.identity/use: "true"label — Pods without this label do not receive federated tokens. Enable viaserviceAccount.azureWorkloadIdentity: true
