Azure
Bring Your Own Cloud (BYOC) deployment on Microsoft Azure. The ekai team runs the deployment automatically using Terraform and GitHub Actions — you don't operate any of it. To make that possible, your team provisions two things in your Azure tenant:
- A service principal in Microsoft Entra ID (the identity ekai's automation uses)
- A resource group named
ekai-saas-<DeploymentName>— for exampleekai-saas-CompanyX
Everything ekai deploys lives inside that single resource group.
Architecture components
- AKS (Azure Kubernetes Service) — application runtime
- Azure Database for PostgreSQL (Flexible Server) — database
- Redis Stack — cache and vector search
- MinIO (S3-compatible) — object storage
- Azure Container Registry (ACR) — container images
- Azure Key Vault — secrets
- Neo4j AuraDB (Azure Marketplace) — managed knowledge graph
Customer setup
These steps are done once by your Azure administrator. The result is a single-tenant service principal that ekai's automation uses — scoped to your ekai-saas-<DeploymentName> resource group only, with no subscription-wide access.
Who runs these steps: your Azure administrator — someone who can register applications and grant admin consent in Entra ID, and who can assign roles on the target subscription / resource group.
The setup falls into three parts:
- Resource group — the boundary everything deploys into
- Entra ID — service principal — the identity ekai's automation authenticates as
- Resource group permissions — scoping that service principal to the resource group only
1. Create the resource group
Name it ekai-saas-<DeploymentName> (e.g. ekai-saas-CompanyX). Everything ekai deploys lives inside this single resource group.
2. Entra ID — service principal
All four configurations below apply to the same service principal. Create it once, then come back to apply secrets, API permissions, and the directory role.
2a. Register the service principal
Entra ID → App registrations → New registration
- Name:
ekai-terraform-<env>(e.g.ekai-terraform-prod) - Account type: Single tenant
- Record the Application (client) ID and Directory (tenant) ID
2b. Create a client secret
On the app page → Certificates & secrets → New client secret
- Description:
terraform-ci - Expiry: per your policy (e.g. 24 months)
- Copy the Value immediately — Azure displays it only once.
2c. Grant a single Microsoft Graph permission
On the app → API permissions → Add → Microsoft Graph → Application permissions
- Add
Application.ReadWrite.OwnedBy - Click Grant admin consent
OwnedBy means the service principal can only manage app registrations it created itself — it cannot see or modify any other app in your tenant. ekai's automation creates one app registration per deployment to enable GitHub OIDC federation for CI/CD.
2d. Assign the Application Administrator directory role
Entra ID → Roles and administrators → Application Administrator → Add assignments → select the ekai-terraform-<env> service principal.
This is the only directory-level role required. Azure does not allow this role to be scoped to a resource group, which is why it lives here in Entra ID rather than in the resource-group permissions below.
3. Resource group permissions
Everything below scopes the service principal to your ekai-saas-<DeploymentName> resource group only. It receives no subscription-wide permissions, no Owner role, and no User Access Administrator role.
3a. Create a custom role limited to the resource group
One-time per subscription. Subscription → Access control (IAM) → Add custom role
- Name:
Ekai AKS Role Assigner - Assignable scope:
/subscriptions/<sub-id>/resourceGroups/ekai-saas-<DeploymentName> - Permissions (three actions only):
Microsoft.Authorization/roleAssignments/readMicrosoft.Authorization/roleAssignments/writeMicrosoft.Authorization/roleAssignments/delete
This lets ekai grant the AKS cluster permission to pull container images from ACR — nothing else.
3b. Assign the three roles to the service principal
Resource groups → ekai-saas-<DeploymentName> → Access control (IAM) → assign the ekai-terraform-<env> service principal these three roles:
ContributorStorage Blob Data ContributorEkai AKS Role Assigner(the custom role from step 3a)
What to share with ekai
- Application (client) ID
- Directory (tenant) ID
- Subscription ID
- Resource group name (
ekai-saas-<DeploymentName>)
Any secrets (database credentials, ArgoCD admin password, etc.) are exchanged through Azure Key Vault inside the resource group — never over email or chat.
Repeat sections 2 and 3 per environment if you'd like separate service principals (e.g. dev, prod).