Single-Account Minimum AWS Deployment
Companion docs: aws-deploy.md for the full multi-account hybrid topology; aws-runbook.md for the operational playbook.
The cheapest deployable AlphaSwarm on AWS. Target cost: ~$340/month fixed
- Bedrock token spend. Skips multi-account, EKS, MSK, AgentCore Runtime, Knowledge Base, CloudFront, and the EventBridge nightly backtest path. Use it as a stepping stone before promoting to the full topology.
It is no longer a single admin task: it runs five ECS Fargate services
behind one ALB — the admin BFF (alphaswarm-admin) + admin UI
(alphaswarm-admin-frontend), the consolidated core-API gateway
(alphaswarm-api), the hosted alpha UI (alphaswarm-ui), and the browser
IDE (alphaswarm-ide). The legacy demo UI is not part of the current alpha
testing deployment.
What you get
Pieces composed
| Tier | Module | Cost/mo |
|---|---|---|
| Network | infrastructure/modules/vpc (2 AZ, single NAT) | ~$32 |
| Ingress | infrastructure/modules/alb | ~$22 |
| Database | infrastructure/modules/rds-postgres (db.t4g.medium) | ~$45 |
| Cache | inline ElastiCache (cache.t4g.small, 1 node) | ~$25 |
| Compute | infrastructure/modules/ecs-fargate-control-plane (5 Fargate services — see breakdown below) | ~$216 |
| Identity | infrastructure/modules/cognito-userpool (first 50k MAU free) | $0 |
| Container registry | infrastructure/modules/ecr-repositories (5 repos) | ~$1 |
| Logs | CloudWatch Logs (~1 GB ingest) | <$1 |
| LLM | Amazon Bedrock Claude Haiku 4.5 (variable) | $? per use |
| Fixed total | ~$340 |
Fargate compute breakdown
The minimum is no longer a single admin task — it runs five Fargate
services behind the shared ALB. Approximate on-demand us-east-1 Fargate
cost (recompute precisely with the AWS pricing tooling before quoting):
| Service (ECS name) | vCPU / RAM | Arch | Cost/mo |
|---|---|---|---|
alphaswarm-admin-minimum (admin BFF) | 1 / 2 GB | X86_64 | ~$36 |
alphaswarm-frontend-minimum (admin UI) | 0.5 / 1 GB | X86_64 | ~$18 |
alphaswarm-api-minimum (core-API gateway) | 2 / 8 GB | ARM64 | ~$68 |
alphaswarm-ui-minimum (hosted alpha UI) | 1 / 2 GB | X86_64 | ~$36 |
alphaswarm-ide-minimum (Theia IDE) | 2 / 4 GB | ARM64 | ~$58 |
| Compute total | ~$216 |
admin + frontend are built linux/amd64 by the alphaswarm_admin CI and
run X86_64; api + ide are Graviton-native and run ARM64; ui runs
X86_64. Each service's Terraform task definition carries
ignore_changes = [task_definition], so the live image + task-def revision +
CPU architecture are owned by the CI rollout, not terraform apply.
Files this guide refers to
- alphaswarm_platform/infrastructure/envs/minimum/ — infrastructure tier (VPC + ECR + RDS + Redis + Bedrock invoke IAM)
- alphaswarm_platform/terraform/environments/minimum/ — application tier (Cognito + ALB + ECS Fargate)
- alphaswarm_platform/configs/terraform/minimum.yaml
—
TerraformStackSpecfor thealphaswarm deployCLI - alphaswarm_platform/configs/deployment/topology.yaml
targets.aws-minimum— topology target binding
Six steps to live
1. Enable Bedrock model access (manual, console)
Console → Bedrock → Model access → request Anthropic Claude Haiku 4.5. Approval is usually instant. Only this model needs access for the minimum — Claude Sonnet 4.5 + Titan Embed v2 can wait until you add the Knowledge Base.
2. Bootstrap the state backend
cd alphaswarm_platform/infrastructure/bootstrap
terraform init
terraform apply -auto-approve
terraform output -json | tee /tmp/bootstrap.json
This is the only place admin creds are required. The stack ships:
- S3 state bucket (KMS-encrypted, Object Lock GOVERNANCE)
- DynamoDB lock table
- KMS CMK for workload encryption
- GitHub OIDC provider
3. Apply the infrastructure tier
cd alphaswarm_platform/infrastructure/envs/minimum
sed "s|<account-id>|$(jq -r .account_id.value /tmp/bootstrap.json)|" \
backend.hcl.example > backend.hcl
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars: paste the kms_key_arn + external_id +
# github_oidc_provider_arn from /tmp/bootstrap.json.
terraform init -backend-config=backend.hcl
terraform apply
~12 minutes (RDS provisioning is the long pole). Outputs include the ALB-ready VPC + every SSM parameter the application tier reads.
4. Push the first image
The admin build runs on a push to qa, on any v* tag, or via a manual
workflow_dispatch:
git tag v0.1.0-min
git push origin v0.1.0-min
build-publish.yml in alphaswarm_admin
builds + pushes alphaswarm-admin and alphaswarm-admin-frontend to ECR.
Each image is tagged with the commit SHA (:${{ github.sha }}, not the
git tag — the ECR repos are immutable). The
alphaswarm-admin-minimum-github-actions-apply role from step 3 is what the
workflow assumes via OIDC.
5. Apply the application tier
cd alphaswarm_platform/terraform/environments/minimum
sed "s|<account-id>|$(jq -r .account_id.value /tmp/bootstrap.json)|" \
backend.hcl.example > backend.hcl
cp terraform.tfvars.example terraform.tfvars
# Edit terraform.tfvars: paste the acm_certificate_arn_alb + set
# admin_image_tag / frontend_image_tag to the commit-SHA tag the build
# pushed. These only seed the FIRST task def — the services carry
# ignore_changes = [task_definition], so CI rollouts own the tag thereafter.
terraform init -backend-config=backend.hcl
terraform apply
~5 minutes. The ALB DNS appears in the outputs.
6. Configure AlphaSwarm runtime
The application reads the deployment endpoints from
/alphaswarm/minimum/* SSM. Set the env vars on the ECS task definition (or
via the application's Settings overrides):
ALPHASWARM_LLM_PROVIDER=bedrock
ALPHASWARM_BEDROCK_REGION=us-east-1
ALPHASWARM_AUTH_PROVIDER=aws_cognito
ALPHASWARM_AUTH_OIDC_ISSUER=<cognito_user_pool_endpoint from outputs>
ALPHASWARM_DEPLOY_TARGET=aws
ALPHASWARM_DATABASE_URL=postgresql+psycopg://<auth from Secrets Manager>@<rds_endpoint>:5432/alphaswarm
ALPHASWARM_REDIS_URL=rediss://<redis_endpoint>:6379/0
The matching bedrock ProviderSpec is already in
alphaswarm/llm/providers/catalog.py
(shipped in Phase D of the AWS hybrid rollout); no code change needed.
Verify
# Hit the ALB:
curl -sS https://$(terraform -chdir=alphaswarm_platform/terraform/environments/minimum \
output -raw alb_dns_name)/healthz
# Call Bedrock through the application:
curl -sS https://<alb-dns>/api/llm/echo \
-H "Authorization: Bearer <cognito-jwt>" \
-d '{"prompt": "ping"}'
The application's router_complete injects aws_region_name=us-east-1
on the Bedrock call (_bedrock_extra_kwargs in
alphaswarm/llm/providers/router.py);
boto3 walks the chain to the ECS task role's IAM credentials.
Rebuild + redeploy via CI/CD (admin + alpha UI)
Image rebuilds for the running ECS services are driven by GitHub Actions
in each service repo — OIDC only: no GitHub PAT and no cross-repo
dispatch. Each workflow assumes the shared apply role, builds + pushes
the image to ECR, registers a new ECS task-definition revision (swapping
only the app container image and preserving the adot-collector
sidecar), updates the service, and waits for services-stable.
| Surface | Repo / workflow | ECS service(s) | ECR repo(s) |
|---|---|---|---|
| Admin BFF + admin UI | alphaswarm_admin → .github/workflows/build-publish.yml | alphaswarm-admin-minimum, alphaswarm-frontend-minimum | alphaswarm-admin, alphaswarm-admin-frontend |
Hosted alpha (alpha.alpha-swarm.ai) | alphaswarm_ui → .github/workflows/build-deploy.yml | alphaswarm-ui-minimum | alphaswarm-ui |
All three services run in cluster alphaswarm-cluster-minimum
(us-east-1, Fargate X86_64 / amd64 — arm64 support was removed as it
came from a legacy hardware setup). The workflows build linux/amd64
only (no QEMU emulation) and the deploy step pins
runtimePlatform.cpuArchitecture = X86_64 on the new task-def revision.
Required GitHub repo variables
Set on both alphaswarm_admin and alphaswarm_ui (Settings →
Secrets and variables → Actions → Variables):
| Variable | Value |
|---|---|
AWS_APPLY_ROLE_ARN | arn:aws:iam::<account>:role/alphaswarm-admin-minimum-github-actions-apply |
ECR_REGISTRY | <account>.dkr.ecr.us-east-1.amazonaws.com |
SHARED_ACCOUNT_ID | <account> (CodeArtifact domain owner; admin build only) |
AWS_REGION | us-east-1 |
The apply role's OIDC trust (token.actions.githubusercontent.com:sub)
allows the alphaswarm_platform and alphaswarm_admin repos on
refs/heads/main, refs/heads/qa, and environment:minimum (development
is a plan-only / read-only ref). No secrets are needed on either repo — all
AWS access is via OIDC.
The
alphaswarm_uialpha build deploys from the alpha-testing branch and assumes this same apply role, so the role must also trust the matchingalphaswarm_uiref. Per the committed IaC it may not yet — addalphaswarm_uitogithub_deployer_reposand the alpha-testing ref to the apply role'sapply_ref_patternsin alphaswarm_platform/infrastructure/envs/minimum before the alpha UI's OIDC deploy can assume it.
CodeArtifact (admin backend only)
The admin backend image vendors the private alphaswarm_core package
from the CodeArtifact PyPI alphaswarm/alphaswarm-pypi; its build
backend (hatchling) resolves from public PyPI via --extra-index-url.
Republish core after changing alphaswarm_core:
cd alphaswarm_core && python -m build --sdist
TOK=$(aws codeartifact get-authorization-token --domain alphaswarm \
--domain-owner <account> --region us-east-1 \
--query authorizationToken --output text)
URL=$(aws codeartifact get-repository-endpoint --domain alphaswarm \
--domain-owner <account> --repository alphaswarm-pypi --format pypi \
--region us-east-1 --query repositoryEndpoint --output text)
TWINE_USERNAME=aws TWINE_PASSWORD="$TOK" \
twine upload --repository-url "$URL" dist/*.tar.gz
Trigger a redeploy
gh workflow run build-publish.yml --repo Alpha-Swarm-ai/alphaswarm_admin --ref qa
gh workflow run build-deploy.yml --repo Alpha-Swarm-ai/alphaswarm_ui --ref development
A push to qa (or a v* tag) in alphaswarm_admin, or a push to
development in alphaswarm_ui, also triggers the matching build
automatically.
Terraform drift: these workflows register ECS task-def revisions out-of-band from alphaswarm_platform/terraform/environments/minimum. Reconcile
admin_image_tag/frontend_image_tag/ui_image_tag(or give the servicesignore_changes = [task_definition]) before the nextterraform apply, or it will roll the services back to the Terraform-pinned image tag.
Promotion path
When ready to outgrow the minimum, add modules one at a time. The SSM-parameter contract means application code doesn't change.
| Add when… | Append to alphaswarm_platform/terraform/environments/minimum/main.tf |
|---|---|
You need a custom domain (admin.alpha-swarm.ai) | module "cloudfront" from infrastructure/modules/cloudfront |
| You need vector search over research docs | module "opensearch_serverless" + module "bedrock_kb" |
| You want AgentCore (8-hour sessions, managed memory) | module "bedrock_agentcore" + a second alphaswarm-agent ECS service |
| You need a Celery worker tier | Stand up infrastructure/envs/dev (full EKS+Karpenter) and add the heritage module "alphaswarm" here |
| You need cross-account isolation | Promote to the full multi-account topology via infrastructure/modules/landing-zone |
Once the full set lands, retarget the topology from
target=aws-minimum to target=aws. The application reads the
same /alphaswarm/${env}/* SSM parameters either way.
Tear down
# Application tier first (Fargate services hold ALB target group
# references that prevent ALB deletion):
cd alphaswarm_platform/terraform/environments/minimum
terraform destroy
# Then infrastructure tier (../../../ from the app-tier dir lands in
# alphaswarm_platform/):
cd ../../../infrastructure/envs/minimum
terraform destroy
# RDS has deletion_protection=true by default — set it to false in
# the module call and re-apply before destroy if you really want it gone.
Data buckets (prevent_destroy = true) are kept on purpose; remove
them manually after confirming no other env references them.