Skip to main content
This page builds the Azure infrastructure for an In-VPC deployment and installs the cluster-wide Kubernetes components the e6data workspace runs on. Run these steps with the Azure CLI (az), kubectl, and Helm. Part 1 provisions Azure infrastructure (run once per cluster). Part 2 installs the Kubernetes platform components (also once per cluster). Per-workspace deployment is covered on the next page, Deploy workspace and e6data.

Infrastructure requirements

Review these before you begin. They apply whether you create a new VNet (Part 1, Step 1) or reuse an existing one.

VNet options

VNet and subnet sizing

With Azure CNI overlay (used here), pods get IPs from the pod CIDR (10.244.0.0/16), not the subnet - so the AKS subnet only needs addresses for nodes, not pods.

Availability zones

e6data spreads workloads across zones for high availability - the engine NodePool lists zones 1, 2, and 3.

Azure quotas (vCPU)

Quota is per VM family, per region. Check and request increases before deploying - increases can take 24–48 hours. Sponsorship and free subscriptions often start with 0 quota for ARM families - request an increase first if az aks create fails with a quota or SKU-not-available error.

VM families

The e6data engine is optimized for ARM64 for price-performance. Confirm your region has the chosen families available.

Existing VNet checklist

If you reuse an existing VNet, confirm:
  • No CIDR overlap between the VNet, pod CIDR (10.244.0.0/16), service CIDR (172.20.0.0/16), or any peered network.
  • The AKS subnet has room for your node count (with CNI overlay, pods don’t consume subnet IPs).
  • Nodes have outbound internet (a NAT Gateway is recommended).
  • Microsoft.Storage and Microsoft.ContainerRegistry service endpoints are enabled on the subnet.

Existing AKS cluster checklist

If you already have an AKS cluster, skip Part 1 Steps 1–3 and verify the cluster meets the requirements below first:
OIDC issuer + Workload Identity is the setting that silently breaks everything if it’s off. Check it first.
Then skip to Step 4 (cluster identity) and continue through Parts 1 and 2 as written.
Steps 1 and 3 also export variables that later steps use. Run Step 0, then set these for your existing VNet and cluster before continuing:
Step 6C.2 also reads the VNet by ${PREFIX}-vnet; substitute your VNet name there if it differs.

Part 1 - Azure infrastructure

By the end of this part you will have a VNet with a NAT Gateway, an AKS cluster with OIDC issuer and Workload Identity enabled, a system node pool and an engine node pool strategy, an ADLS Gen2 storage account, and a workspace Managed Identity federated to the e6data service accounts.

Step 0: Set variables

Step 1: Create the resource group, VNet, and NAT Gateway

Step 2: Create the AKS cluster

Create the cluster with OIDC issuer and Workload Identity enabled, Azure CNI overlay with Cilium, and an ARM64 system pool tainted CriticalAddonsOnly:
Notes:
  • Standard_D2ps_v6 is ARM64. All e6data system images are multi-arch; for x86 use Standard_D4as_v5.
  • The NAT Gateway on the subnet takes precedence for egress even with --outbound-type loadBalancer.
  • To use Entra ID (Azure AD) RBAC for cluster auth, append --enable-aad --enable-azure-rbac --disable-local-accounts --aad-admin-group-object-ids <group-object-id>.

Step 3: Connect and capture cluster outputs

AKS hosts the OIDC issuer for you - there is nothing to create. You only reference its URL when creating federated credentials.

Step 4: Grant the cluster identity network access

The cluster’s control-plane identity needs Network Contributor on the VNet so the Azure cloud provider can manage load balancer backend pools for nodes in your subnet:

Step 5: Container registry access

e6data images are pulled from e6labs.azurecr.io. Choose one option and confirm it with your onboarding engineer (they configure the matching side). Option A - AcrPull role (if e6data grants your kubelet identity access, or you mirror images to your own ACR):
Option B - Pull secret (e6data provides a scoped ACR token). The secret must exist in both the e6operator namespace and the workspace namespace before components install, so create the namespaces now:
With Option B, also reference e6data-acr-pull wherever the guide notes imagePullSecrets (operator values in Step 2.4, NamespaceConfig in the next page).

Step 6: Engine node pool

Engine pods need a user node pool to scale on. Pick one provisioner. The workspace-name label and taint are mandatory - engine pods schedule onto nodes by exactly this label/taint pair. Option A - Static user node pool (simplest):
Option B - Node Auto Provisioning (NAP, managed Karpenter):
Option C - Self-hosted Karpenter (recommended for scale-to-zero engine nodes). This uses the AKS Karpenter provider published in Microsoft’s container registry. It has five sub-steps: identity, cluster values, bootstrap token, Helm install, and the NodeClass/NodePool.

6C.1 - Karpenter Managed Identity and roles

6C.2 - Gather cluster values

6C.3 - Bootstrap token

New nodes use this token to join the cluster. It must be in <6-char-id>.<16-char-secret> format:

6C.4 - Install Karpenter

Create karpenter-values.yaml, substituting the variables set above:

6C.5 - AKSNodeClass and NodePool for engine nodes

The taint workspace-name=<workspace> is what the e6data engine pods tolerate, so nodes are dedicated to the workspace:
Notes:
  • kubernetes.io/arch: arm64 with sku-families D/E/F/L makes Karpenter pick ARM variants. For x86, change arch to amd64.
  • capacity-type includes spot; remove it for on-demand only.
  • A Warning: use v1beta1.AKSNodeClass instead message is a Karpenter 1.7.x deprecation notice - v1alpha2 still works and matches the e6data production templates. Safe to ignore.

Step 7: Create the metadata storage (ADLS Gen2)

e6data stores workspace metadata in an ADLS Gen2 account (hierarchical namespace enabled) with one private container per workspace:
Do not enable blob versioning or soft delete on this account - both break ABFS/Hadoop compatibility, which the engine relies on.
The storage backend URI used later in the workspace config is abfss://${WORKSPACE_NAME}-metadata@${STORAGE_ACCOUNT}.dfs.core.windows.net/.

Step 8: Create the workspace Managed Identity and federated credentials

All e6data workspace components share one user-assigned Managed Identity, with one federated credential per e6data service account that needs Azure access. The core components are engine and console:
When you later enable add-ons (Laminar, Copilot, Metriq), add a federated credential for each of their service accounts against this same identity. The monitoring service account intentionally has no identity binding - it pushes to GreptimeDB with username and password.

Step 9: Role assignments for storage access

Part 1 verification

Record AKS_OIDC_ISSUER, NODE_RESOURCE_GROUP, ENGINE_IDENTITY_CLIENT_ID, STORAGE_ACCOUNT, and the storage backend URI - the workspace deployment uses them.

Part 2 - Kubernetes platform components

This part installs the cluster-level components: an e6operator NodePool, cert-manager, the e6-operator CRDs, the e6-operator controller, and the service-token verifier secret. Karpenter itself was installed in Part 1 Step 6C. e6data provides the operator chart and CRDs during onboarding.
The recommended layout pins cert-manager and the operator onto dedicated e6operator nodes (label app: e6operator, taint workload=e6operator). Step 2.1 creates that NodePool if you run Karpenter. If you use static or NAP node pools instead, omit the nodeSelector/tolerations blocks in Steps 2.2 and 2.4 and let the components run on the system pool.

Step 2.1: e6-operator NodePool (Karpenter only)

Step 2.2: Install cert-manager

The operator’s admission webhooks get their serving certificates from cert-manager, so it is required:

Step 2.3: Install the e6-operator CRDs

The CRDs are applied with kubectl, not Helm, because the combined payload exceeds Helm’s 1 MB release-secret limit. --server-side is required because client-side apply hits the 256 KB annotation limit:
Key CRDs used in workspace deployment: namespaceconfigs, queryrouters, monitoringservices, metadataservices, queryservices, accesstokens, e6catalogs, governances.

Step 2.4: Install the e6-operator controller

Step 2.5: Create the service-token verifier secret

The console authenticates e6_svc_ service tokens against the e6data control plane using a shared verifier secret. The e6-operator reflects this secret into every workspace namespace as <workspace>-cp-verifier.
If this secret is missing, service-token authentication silently fails with 401. Create it now with the value from your onboarding engineer.

Next

Continue to Deploy workspace and e6data.
Last modified on October 1, 2026