ADR-0012: Cloud Architecture Selection (AWS-first)
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:
- Cloud Provider: Which provider(s) to target first?
- Kubernetes: Managed vs self-managed, cluster sizing
- Database: Instance type, availability configuration
- 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.mediumbalances 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.smallsufficient 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
| Risk | Mitigation |
|---|---|
| Cost overrun | Use t3 instances, no Multi-AZ initially |
| Vendor lock-in | Kubernetes abstracts most AWS-specific details |
| Complexity | Start 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)