ADR 031 — One customer compute answer: ECS Fargate; EKS path frozen
- Status: Accepted (2026-07-24)
- Authors: Platform team (go-live Phase 16, §F-5/§F-6)
- Related: ADR 022 (One Gate),
ADR 026 (asctl estate),
alphaswarm_internal/INSTITUTIONAL_GO_LIVE_PLAN.md§F-5/§F-6/§F-7, BYOC deployment — AWS, License issuance and revocation
Context
Go-live §F-6 demanded we "pick and finish ONE client compute answer". Two candidates existed:
- ECS Fargate (minimum-tier pattern). The hosted minimum tier already
runs api/admin/ui/ide on ECS Fargate with a proven task-definition /
Secrets-Manager-injection / ALB pattern, and
customer_account_awsalready provisions an ECS cluster placeholder in every customer account. - EKS (
infrastructure/envs/dev). EKS 1.32 + Karpenter + ESO + ArgoCD — never applied end-to-end, and theawsKubernetes overlay (gp3 StorageClasses, ALB/NLB ingress, IRSA annotations, ExternalDNS) does not exist. Until one path is exercised, "the 76-service topology on client AWS" is fiction.
Running both forks means two secret-delivery mechanisms (SM→ECS vs ESO), two ingress models, two license-delivery stories (env-file vs CSI), and double the unproven surface at exactly the moment the program needs one honest answer.
Decision
ECS Fargate is the one customer compute answer. The §F-5 workload plane
is built into terraform/modules/customer_account_aws (workloads.tf,
Default-OFF behind enable_workload_plane):
- api + Celery worker (light/coordination queues:
default,paper,terraform,ingestion,workflows) + beat (pinned singleton, min-healthy 0% / max 100%) as Fargate services on the existing KB-silo cluster, consuming the module'sworkload_envcontract; - ElastiCache Redis broker with a Terraform-minted AUTH token auto-filled into Secrets Manager (the minimum-tier idiom);
- services
depends_onthe F-2 migration gate — no workload converges onto an unmigrated schema; - license lease + public key delivered as Secrets Manager → ECS
secretsenv injection, written to theALPHASWARM_LICENSE_*_PATHfiles by ansh -ccommand preamble (every runtime image shipsENTRYPOINT []). No CSI driver, no sidecar, no in-plane renewal daemon; - rollouts are governed Terraform applies pinned to
app_versionthrough the One Gate — deliberately noignore_changeson task definitions (the task-def diff is the release-review artifact), diverging from the hosted minimum tier where CI rolls task definitions out-of-band.
The EKS path is frozen, not deleted. infrastructure/envs/dev stays in
the tree as authored reference; no aws k8s overlay will be written, and
enable_secrets_module/enable_eso stay off for customer targets. Freezing
(rather than deleting) preserves the option to thaw for a future customer
whose contract mandates Kubernetes — at which point the missing overlay and
an OpenBao/ESO story must be built and exercised end-to-end before it may be
called an answer.
Consequences
- One secret-delivery mechanism (Secrets Manager → ECS injection), one
ingress model (optional ALB behind
enable_workload_ingress+ the §A-1.4 ACM certificate), one license story. - Queue honesty: the plane drains the light queues + beat. Heavy queues
(
backtest,training,ml,agents,factors,rag),ml.control,hft,lab.cpu, and legacyingestare undrained — hft/lab.cpu/ingest are undrained on every target today (parity, not regression); the heavy-queue executor service is a named defer. - License renewal in ECS is out-of-band: re-seed the secret, then force a new deployment (see the license runbook). Leases expire into grace then 403 otherwise.
- Nothing here is applied anywhere yet: CI proof is fmt + validate +
mock-provider
terraform testplans (the only CI-side count-path evaluation —terraform validatenever evaluates count paths). First real proof is a governed plan/apply in a sandbox customer account. - Anyone proposing customer EKS must supersede this ADR first.