Architecture Decision Log
This document captures all architectural decisions organized by category.
1. Technology Stack
Section titled “1. Technology Stack”| Decision | Choice | Rationale |
|---|---|---|
| Language | TypeScript (latest) | Type safety, modern JS features |
| Runtime | BunJS | Fast, all-in-one (runtime, package manager, test runner) |
| Testing | Bun test + MSW | Native Bun support, HTTP mocking |
| Build | Bun bundler + tsc | Fast bundling + type checking |
| CLI Framework | Commander.js | Mature, widely used |
| Tool Management | Mise | Consistent tool versions across team |
2. Security
Section titled “2. Security”| Decision | Choice | Rationale |
|---|---|---|
| Encryption Algorithm | AES-256-GCM | Industry standard, authenticated |
| Key Derivation | PBKDF2 (Web Crypto) | NIST-standard KDF |
| KDF Iterations | 600,000 | OWASP recommended minimum |
| Passphrase Source | Env var / file / flag | Flexible for CI/CD |
| Encrypted Fields | Sensitive only | Performance, readability |
| Field Detection | Name patterns + Secret<T> | Automatic + explicit |
| SSH Keys | Public only | Private keys not managed by Kyku |
3. Resources (MVP Scope)
Section titled “3. Resources (MVP Scope)”| Resource | Status | Notes |
|---|---|---|
| Vpc | ✅ Included | With region and AZ distribution |
| Subnet | ✅ Included | First-class, public/private |
| Vm | ✅ Included | With AZ distribution |
| SecurityGroup | ✅ Included | With SG-to-SG references |
| LoadBalancer | ✅ Included | With AZ spanning |
| Database | ✅ Included | PostgreSQL, MySQL, MariaDB |
| Identity | ✅ Included | IAM users, service accounts |
| Role | ✅ Included | With hierarchical permissions |
| Storage (S3/Cloud Storage) | ❌ Deferred | Post-MVP |
| K8s Cluster | ❌ Deferred | Post-MVP |
| K8s Deployment | ❌ Deferred | Post-MVP |
4. Regions & Networking
Section titled “4. Regions & Networking”| Decision | Choice | Rationale |
|---|---|---|
| Region Format | Abstract + override | Portable, flexible |
| Abstract Regions | us-east, eu-central, etc. |
User-friendly |
| AZ Distribution | Automatic (default) | High availability |
| Subnet Model | First-class resources | Explicit control when needed |
| Subnet Types | Public + private | Security best practice |
| DB Placement | Always private subnets | Security |
5. State Management
Section titled “5. State Management”| Decision | Choice | Rationale |
|---|---|---|
| State Format | JSON | Human-readable, debuggable |
| State Location | .kyku/state.<env>.json |
Per-environment |
| Encryption | Field-level | Selective, performant |
| Locking | File-based (future) | Prevent concurrent applies |
6. CLI Design
Section titled “6. CLI Design”| Decision | Choice | Rationale |
|---|---|---|
| Commands | plan, apply, output | Core workflow |
| Plan Output | Human-readable text | Easy review |
| Apply Confirmation | Interactive prompt | Prevent accidents |
| Auto-approve | --auto-approve flag |
CI/CD support |
| Secrets in Output | Redacted by default | Security |
| Exit Codes | Standard (0=success, 1=error) | Shell scripting |
7. Provider Support
Section titled “7. Provider Support”| Feature | AWS | GCP | Hetzner |
|---|---|---|---|
| VPC/Network | ✅ Full | ✅ Full | ✅ Full |
| Subnet | ✅ Per-AZ | ✅ Regional | ✅ Simple |
| VM | ✅ Full | ✅ Full | ✅ Full |
| Security Group | ✅ Native | ✅ Firewall Rules | ✅ Firewall |
| Load Balancer | ✅ ALB/NLB | ✅ Cloud LB | ✅ LB |
| Database | ✅ RDS | ✅ Cloud SQL | ❌ |
| Identity/User | ✅ IAM User | ✅ Service Account | ❌ |
| Role | ✅ IAM Role | ✅ Custom Role | ❌ |
Detailed Decision Log
Section titled “Detailed Decision Log”2024-05-10: Initial Architecture
Section titled “2024-05-10: Initial Architecture”Decision: Build universal infrastructure provisioning tool Scope: AWS, GCP, Hetzner | Resources: VM, DB, LB, VPC, Security Groups, IAM
2024-05-10: Technology Stack
Section titled “2024-05-10: Technology Stack”Decision: TypeScript + BunJS + Mise Rationale: Modern, fast, type-safe
2024-05-10: Security Groups
Section titled “2024-05-10: Security Groups”Decision: SG-to-SG references in rules Rationale: Natural security model for infrastructure
2024-05-10: Database Auth
Section titled “2024-05-10: Database Auth”Decision: IAM auth primary, password legacy Rationale: Security best practice
2024-05-10: Regions & Subnets
Section titled “2024-05-10: Regions & Subnets”Decision: Abstract regions, first-class subnets Rationale: Portability across providers, explicit control when needed
2024-05-10: Secret Encryption
Section titled “2024-05-10: Secret Encryption”Decision: AES-256-GCM + Argon2id → Superseded by 2024-05-13 (PBKDF2)
2024-05-10: K8s Deferral
Section titled “2024-05-10: K8s Deferral”Decision: Post-MVP Rationale: Focus on infrastructure primitives first
2024-05-11: CI Authentication Strategy
Section titled “2024-05-11: CI Authentication Strategy”Decision: Hybrid — OIDC automatic in CI, standard credential chains locally Rationale: CI platforms provide OIDC tokens natively; local dev uses SDK defaults
2024-05-11: AWS CI Auth
Section titled “2024-05-11: AWS CI Auth”Decision: AssumeRoleWithWebIdentity via STS, inject temp creds into env vars
Config: KYKU_AWS_ROLE_ARN, KYKU_AWS_ROLE_SESSION_NAME
2024-05-11: GCP CI Auth
Section titled “2024-05-11: GCP CI Auth”Decision: Workload Identity Federation + service account impersonation
Config: KYKU_GCP_WORKLOAD_PROVIDER, KYKU_GCP_SERVICE_ACCOUNT, KYKU_GCP_PROJECT_ID
2024-05-11: Hetzner Auth
Section titled “2024-05-11: Hetzner Auth”Decision: No OIDC support, continue with HCLOUD_TOKEN
Rationale: Hetzner Cloud API does not support OIDC federation
2024-05-13: Encryption — PBKDF2 over Argon2id
Section titled “2024-05-13: Encryption — PBKDF2 over Argon2id”Decision: Use Web Crypto PBKDF2 (600,000 iterations, SHA-256)
Rationale: Bun.password.hash() returns formatted hash strings, not raw key bytes. PBKDF2 is the correct tool for deriving AES-256-GCM keys.
2024-05-13: Output Propagation
Section titled “2024-05-13: Output Propagation”Decision: Output values persisted to state file after resource creation. Cross-resource output references create implicit dependency edges.
2024-05-13: State Backup
Section titled “2024-05-13: State Backup”Decision: Timestamped state backup before every apply execution.
Rationale: Safety net for failed applies.
2024-05-13: AWS VPC Networking
Section titled “2024-05-13: AWS VPC Networking”Decision: VPC includes IGW, NAT Gateways (per AZ), route tables (public + private). Rationale: VPCs without IGW/NAT are non-functional. Auto-generating avoids requiring users to understand AWS networking primitives.
2024-05-13: RDS Instance Types
Section titled “2024-05-13: RDS Instance Types”Decision: Separate instance type mapping (db.t3.* vs t3.*).
Rationale: Cloud managed databases use different naming conventions than compute.
2024-05-13: GCP Client Libraries
Section titled “2024-05-13: GCP Client Libraries”Decision: @google-cloud/compute and @google-cloud/iam (modular packages).
Rationale: Smaller install, proper ESM support. Monolithic googleapis has CJS/ESM issues.
2024-05-13: IAM Instance Profiles
Section titled “2024-05-13: IAM Instance Profiles”Decision: EC2 instances automatically get IAM instance profiles for SGs with associated IAM roles. Rationale: Database IAM auth requires instance profiles.
2024-05-13: Resource Classes
Section titled “2024-05-13: Resource Classes”Decision: Resources are classes with constructors, not plain interfaces.
Rationale: Auto-generated UUIDs, outputs proxy, natural user API (new Vpc({...})).
2024-05-13: Output References
Section titled “2024-05-13: Output References”Decision: resource.outputs.<key> returns OutputValue placeholder. Template literals stringify to ${output:<id>:<key>}. Engine resolves during apply.
2024-05-13: CustomResource Registry
Section titled “2024-05-13: CustomResource Registry”Decision: Handlers referenced by handlerId string via global CustomResourceRegistry.
Rationale: Functions cannot be serialized to JSON state. Registry allows state to survive plan/apply runs.
2024-05-13: Auto-Subnet Visibility
Section titled “2024-05-13: Auto-Subnet Visibility”Decision: Auto-created subnets injected as full Subnet resources with deterministic IDs.
Rationale: Users need to reference auto-subnets. First-class resources make them visible in graph and state.
2024-05-13: Dynamic Provider Imports
Section titled “2024-05-13: Dynamic Provider Imports”Decision: CLI provider factory uses dynamic import().
Rationale: Avoids bundling all provider SDKs. Reduces CLI startup time.
2024-05-13: Destroy Uses State
Section titled “2024-05-13: Destroy Uses State”Decision: kyku destroy operates on state file, not config.
Rationale: Resources removed from config would otherwise be orphaned.
2024-05-13: AWS ELB v2 Health Checks
Section titled “2024-05-13: AWS ELB v2 Health Checks”Decision: Target Groups for health checks (ELB v2 API).
Rationale: ConfigureHealthCheckCommand does not exist in ELB v2 SDK.