Skip to main content
This blueprint walks through a full production deployment of Cognisafe on Azure Kubernetes Service (AKS). It covers namespace layout, Kubernetes manifests for all four components, secret management via Azure Key Vault CSI, TLS termination via cert-manager, autoscaling, and observability. The goal is a cluster you can hand to an on-call engineer and have them understand without tribal knowledge.

Prerequisites

  • AKS cluster running Kubernetes 1.28+ (az aks get-versions to verify availability in your region)
  • kubectl configured against the target cluster (az aks get-credentials --resource-group <rg> --name <cluster>)
  • Helm 3.12+
  • Azure CLI 2.55+ with the aks-preview extension
  • Azure Container Registry (ACR) attached to the cluster (az aks update --attach-acr <acr-name>)
  • cert-manager 1.14+ installed in the cluster (see below)
  • NGINX Ingress Controller installed (see below)
  • Azure Key Vault CSI driver enabled on the cluster
The Key Vault CSI driver and cert-manager are not installed by default on AKS. Install them before applying these manifests. Installation commands are listed in the Install cluster add-ons section.

Architecture overview

Install cluster add-ons

1

Enable Key Vault CSI driver

2

Install cert-manager

3

Install NGINX Ingress Controller

Wait for the LoadBalancer IP to be assigned:
Point your DNS A records (proxy.cognisafe.yourcompany.com, api.cognisafe.yourcompany.com, cognisafe.yourcompany.com) at this IP before cert-manager can issue certificates.

Namespace and ResourceQuota

ConfigMap

Non-secret configuration shared across deployments. Update the values for your environment.

Secret management via Azure Key Vault CSI

Store all sensitive values in Azure Key Vault, then mount them as Kubernetes Secrets using the Secrets Store CSI driver. This avoids storing secrets in etcd or in manifests.

Enable workload identity on the cluster

Create a managed identity and Key Vault access policy

ServiceAccount

SecretProviderClass

The Kubernetes Secret (cognisafe-secrets) is only created after the first pod mounts the CSI volume. You must deploy at least one pod (any of the four components) before the Secret object exists. The manifests below include the CSI volume mount in every Deployment precisely so the Secret is hydrated on first rollout.

Proxy Deployment

API Deployment

The migrate init container runs alembic upgrade head on every pod start. Because Alembic migrations are idempotent, this is safe with multiple replicas — only the first pod to acquire the advisory lock will run pending migrations; the rest will no-op. This avoids the need for a separate migration Job.

Web Deployment

Safety Worker Deployment

The safety worker has no ingress — it only pulls from Redis and writes to PostgreSQL.

HorizontalPodAutoscaler for safety-worker

Scale the worker pool based on CPU, since safety scoring is CPU/network-bound during LLM calls.
If your Redis queue depth is a more meaningful signal than CPU (e.g., burst scoring jobs after a traffic spike), consider adding a custom metric via KEDA (ScaledObject targeting the safety_score_jobs list length). KEDA’s Azure Cache for Redis scaler handles this directly.

TLS Ingress with cert-manager

ClusterIssuer (Let’s Encrypt production)

Ingress

Apply all manifests

Node pool recommendations

Add the corresponding toleration to the safety-worker Deployment spec:
Spot nodes can be evicted with 30 seconds notice. The safety worker must handle SIGTERM gracefully — finish the current scoring job, then exit. The safety worker loop should catch KeyboardInterrupt/SIGTERM and drain the in-flight job before stopping. Ensure terminationGracePeriodSeconds is set to at least 60 seconds in the pod spec.

Monitoring: Azure Monitor + Container Insights

After enabling Container Insights, navigate to the AKS cluster in the Azure Portal → MonitoringInsights to see per-node CPU/memory, per-pod logs, and live event streams. Key metrics to alert on: