Skip to content

AWS vs Azure

Nexa is customer-managed and installs on either AWS or Azure. This page is for DataReadyAI engineers maintaining both paths: it lists what actually differs between the clouds and, just as important, what is intentionally the same on both. The two cloud stacks are deliberately kept as close as possible — same Kubernetes, same ingress, same TLS pattern — so most of the platform is cloud-agnostic and only the substrate changes.

The AWS platform is provisioned by aws-iac; the Azure platform by nexa-azure-app-iac. Both use Terragrunt with per-environment environments/{dev,test,prod}.tfvars (driven by TF_VAR_environment), not Terraform workspaces.

Regardless of cloud, the runtime is identical: Kubernetes 1.34 running the same container images, with in-cluster Envoy Gateway (Gateway API) behind a cloud load balancer, TLS from cert-manager via Let’s Encrypt DNS-01, GitOps by ArgoCD, and secrets injected by the Secrets Store CSI driver. There is no cloud-native ingress controller (no ALB, no Application Gateway) and no cloud-native certificate service (no ACM) in the request path — that keeps the deploy manifests in nexa-deployments largely cloud-portable. DNS for the Azure environments is delegated from Route53 (<env>.az.nexa-drai.com).

Concern AWS (aws-iac) Azure (nexa-azure-app-iac)
Kubernetes EKS 1.34 (aws_eks_cluster, managed node groups) AKS 1.34 (azurerm_kubernetes_cluster, overlay CNI, KEDA)
Pod → cloud identity EKS Pod Identity (aws_eks_pod_identity_association) Workload Identity (azurerm_federated_identity_credential, OIDC issuer + system:serviceaccount:<ns>:<sa> subject)
Container registry ECR, per-service repos (aws-iac-<service>), GitHub-OIDC push single ACR Premium (acrnexadev001), AcrPull role on the kubelet identity
App database RDS PostgreSQL 15 (subnet group + SG on 5432) PostgreSQL Flexible Server 15 (VNet-delegated subnet + private DNS zone)
Secrets store AWS Secrets Manager Azure Key Vault
Config/params SSM Parameter Store Key Vault
Network aws_vpc 10.0.0.0/16, public/private subnets, single NAT azurerm_virtual_network 10.1.0.0/16, delegated subnets (aks/pe/postgres/dbx), NAT gateway
DNS Route53 (authoritative zone) Azure DNS zone <env>.az.nexa-drai.com, delegated from Route53
Terraform state S3 (aws-iac-terraform-state-*, use_lockfile=true) Azure Blob (stnexatfstate001 / tfstate)
Region (default) ap-southeast-1 australiaeast

This is the difference to internalize because it shapes every service’s ServiceAccount wiring.

Workloads assume AWS IAM via EKS Pod Identity. aws-iac associates a ServiceAccount with an IAM role through aws_eks_pod_identity_association — there is a reusable per-service module so nexa-backend, nexa-agents-api, nexa-databricks-api, etc. each get scoped access (typically to their Secrets Manager secret). The same mechanism grants cert-manager Route53 access (DNS-01) and gives argocd-image-updater ECR read. GitHub Actions pushes to ECR via a github-oidc provider role, not static keys.

If the customer runs Databricks, where the workspace comes from also depends on the cloud:

  • On Azure, the Databricks workspace itself is provisioned by nexa-azure-app-iac (stacks/06-databricksazurerm_databricks_workspace, VNet-injected, plus an access connector for Unity Catalog). Workspace-level governance (Unity Catalog, warehouses, clusters) is then applied by nexa-azure-databricks-iac (2 stacks), with storage credentials backed by the Azure access connector → ADLS and secret scopes backed by Key Vault.
  • On AWS, the whole Databricks E2/MWS workspace is built from scratch by drai-customer-databricks-iac (6 stacks, based on the Databricks Security Reference Architecture): databricks_mws_* resources, S3 + KMS customer-managed keys, PrivateLink, VPC peering to the app VPC, metastore creation, and an optional security-analysis-tool module. Storage credentials are IAM role ARNs → S3; node types are m5/i3 (vs Azure’s Standard_D/E-series).

Both clouds build the same images in GitHub Actions, but publish through different workflows. build-push-ecr.yml (the fuller pipeline — Gitleaks, Trivy, keyless Cosign, SBOM/provenance) targets AWS; build-push-acr.yml targets Azure and is lighter (Trivy via the action, no Gitleaks/Cosign/SBOM). See CI/CD for the full breakdown, and note that image tags follow the same branch-per-env convention on both.