ADR-0012: Cloud Architecture Selection (AWS-first)

Status: ACCEPTED Date: 2026-01-09 Author: Claude (Architect) Task: Task-085

Context

Jorvis is transitioning from local development to production-ready deployment. Phase M (Deployment & Operations) requires Infrastructure as Code (IaC) to automate provisioning. Key decisions needed:

  1. Cloud Provider: Which provider(s) to target first?
  2. Kubernetes: Managed vs self-managed, cluster sizing
  3. Database: Instance type, availability configuration
  4. Terraform State: Backend storage and locking

Current State

  • Local development uses Docker Compose
  • Helm charts exist (analytics-platform/charts/jorvis/)
  • No cloud infrastructure provisioned
  • Greenfield Terraform state

Decision

1. Cloud Provider: AWS First

Choice: AWS as primary, GCP as future expansion (Task-088+)

Rationale:

  • Superior Terraform ecosystem maturity
  • More community modules and examples available
  • Team familiarity (assumed)
  • GCP can be added later without architectural changes

Alternatives Considered:

  • GCP First: Good Kubernetes native support, but smaller Terraform ecosystem
  • Multi-cloud from start: Excessive complexity for initial deployment

2. Kubernetes: EKS Managed

Choice: Amazon EKS (Elastic Kubernetes Service)

Configuration:

  • Managed control plane (EKS)
  • 2 worker nodes minimum
  • Instance type: t3.medium (2 vCPU, 4GB RAM)
  • Level: Development starter (production hardening in Task-086+)

Rationale:

  • Managed control plane reduces operational burden
  • 2 nodes provides basic HA for workloads
  • t3.medium balances cost and capability for initial deployment
  • Can scale horizontally as needed

3. Database: RDS PostgreSQL

Choice: Amazon RDS for PostgreSQL

Configuration:

  • Instance class: db.t3.small (2 vCPU, 2GB RAM)
  • Engine: PostgreSQL 15.4 (matches Terraform defaults, supports AGE extension)
  • Storage: 20GB gp3 (expandable)
  • Multi-AZ: No for development, Yes for production

Rationale:

  • Aligns with existing local PostgreSQL setup
  • RDS handles backups, patching, monitoring
  • db.t3.small sufficient for development workloads
  • Multi-AZ deferred to reduce initial costs

4. Terraform State: S3 + DynamoDB

Choice: S3 bucket with DynamoDB state locking

Configuration:

  • S3 bucket: jorvis-terraform-state-{account_id}
  • DynamoDB table: jorvis-terraform-locks
  • Encryption: Server-side (SSE-S3)
  • Versioning: Enabled

Rationale:

  • Industry standard for AWS Terraform
  • State locking prevents concurrent modifications
  • Versioning enables state recovery
  • No existing state to migrate

Infrastructure Layout

infra/terraform/
├── README.md              # Deployment guide
├── main.tf                # Root module
├── variables.tf           # Input variables
├── outputs.tf             # Output values
├── versions.tf            # Provider versions
├── backend.tf             # S3 state config
└── modules/
    ├── vpc/               # VPC, subnets, NAT
    ├── eks/               # EKS cluster
    ├── rds/               # RDS PostgreSQL
    └── state-backend/     # Bootstrap S3/DynamoDB

Consequences

Positive

  • Clear path from development to production
  • Managed services reduce operational complexity
  • Terraform enables reproducible infrastructure
  • AWS-first allows rapid iteration

Negative

  • AWS vendor lock-in for initial deployment
  • EKS has learning curve vs simpler alternatives (ECS, App Runner)
  • Cost implications (~$150-300/month for minimal setup)

Risks & Mitigations

RiskMitigation
Cost overrunUse t3 instances, no Multi-AZ initially
Vendor lock-inKubernetes abstracts most AWS-specific details
ComplexityStart minimal, expand incrementally

Implementation Notes

  • Use Terraform variables for region, instance sizes, environment
  • No secrets in code; reference AWS Secrets Manager or SSM Parameter Store
  • Provider versions must be pinned
  • Evidence required in docs/agent_ops/OUTBOX/task_085_evidence.md

Approval

  • Proposed by: Claude (Architect)
  • Date: 2026-01-09
  • Reviewed by: Codex (Gatekeeper)
  • Approved by: George (User)