Production cutover — api.drape.to → ECS/RDS (2026-08-31)
This is the operational record of executing the ADR-0002 prod cutover. api.drape.to now serves from the ECS Fargate prod stack over a valid ACM certificate. The Lightsail box was already gone before this work; the trigger was Kenji reporting the landing-page sign-up (waitlist) was erroring — root cause was that api.drape.to no longer resolved.
https://api.drape.to is live: /api/status → 200 {"status":"ok","database":"postgresql"} with a valid cert, /api/health → healthy (redis ok, postgresql ok, fal + fashn configured), and the LP waitlist POST /api/marketing/waitlist returns success from https://drape.to.
What changed
| Piece | Before | After |
|---|---|---|
api.drape.to DNS | no record (Lightsail gone) | Route 53 alias A → drape-alb |
| TLS | old ACM cert timed out; legacy cert was CN=staging.drape.to (iOS-ATS blocker) | new ACM cert for api.drape.to + dev-api.drape.to, issued and attached to a 443 listener |
| ALB listener | HTTP:80 only | added HTTPS:443 (TLS13-1-2), host rule api.drape.to → drape-prod-tg |
drape-prod service | desired=0 (off) | desired=1, healthy on task def drape-prod:2 |
| prod DB | drape-postgres-prod (never turned on, contents unverified) | drape-postgres-prod-live — restored from the live data |
| prod task def secrets | 3 keys injected (DATABASE_URL, JWT_SECRET_KEY, ADMIN_PASSWORD) | 14 keys injected (adds FAL, FASHN, Supabase, Stripe, Upstash, OpenAI, Sentry) |
Procedure executed
- ACM. Old cert had
VALIDATION_TIMED_OUT. Requested a fresh DNS-validated cert (api.drape.to+dev-api.drape.to); added the two validation CNAMEs in Route 53; cert ISSUED. - Safety. Manual pre-cutover snapshots of both RDS instances (
drape-postgresanddrape-postgres-prod). - Live-data restore. Encrypt-copied the
drape-postgressnapshot (source was unencrypted; kept prod encrypted via the existing KMS key) and restored it to a new instancedrape-postgres-prod-live— private subnets (drape-pg-subnets), same SG, not public. - Repoint. Updated
prod-keysDATABASE_URLto the restored instance (reusing the copied DB's working credentials), preserving all other fields. - Secrets. Pulled the real SaaS keys from the old Render
Drape-backendservice intoprod-keys(values never surfaced — names-only tooling). Registered task defdrape-prod:2injecting every non-placeholder key, then scaleddrape-prodto 1. - Ingress. Created the HTTPS:443 listener with the new cert + the
api.drape.to→drape-prod-tgrule; added the Route 53 alias. - Verify. DNS resolves to the ALB; cert verifies;
/api/status+/api/healthhealthy; waitlist write succeeds over HTTPS withOrigin: https://drape.to.
The other session's original drape-postgres-prod was left untouched as a fallback, and pre-cutover snapshots of both databases are retained. Rollback = point the api.drape.to alias/host-rule back, or restore from a snapshot.
Reference (us-east-1, acct 230790682930)
- ALB
drape-alb—drape-alb-1305867817.us-east-1.elb.amazonaws.com(zoneZ35SXDOTRQ7X7K) - Prod service
drape-prod/ target groupdrape-prod-tg/ task defdrape-prod:2at cutover (inventory 2026-09-17 sawdrape-prod:10/drape-dev:22on clusterdrape) - Prod DB
drape-postgres-prod-live(encrypted, private) — cutover pointeddrape/backend/prod-keysDATABASE_URLhere. Stage 2A did not re-read secret values; treat the host mapping as docs-supported, not API-proven from the secret payload. - Cert
arn:aws:acm:us-east-1:230790682930:certificate/19f9816e-8896-4a4b-9a60-c03c133888ba - Route 53 zone
drape.to—Z00780563EFBECXPWSBK4
Open items
- Catalog appears empty. Prod and dev both return empty
/api/products,/api/brands,/api/store/,/api/stats/active-users. Prod is a faithful copy of dev, so nothing was lost in the cutover — but confirm whether the historical catalog/users are actually in RDS or were left on the (now-gone) Lightsail box. Needs a direct row-count check. - 9 keys still placeholder in
prod-keys:RESEND_*,MUX_*,STRIPE_PRICE_*(4),INBOUND_EMAIL_WEBHOOK_SECRET, plus Langfuse (blank in Render too). Email, video, and subscription-pricing features stay off until filled; then add them to the task def. - Revoke the temporary Render API key (
temp-key-recovery-revoke-after) used to recover the secrets. - RDS
drape-postgres-prodis a LEGACY CANDIDATE / rollback leftover — not approved for deletion. Stage 2A classification:drape-postgres-prod-live= ACTIVE PROD (docs-supported);drape-postgres= probable ACTIVE DEV (public; README shortcut; not secret-read proven). Do not decommission any of the three instances from this record.
Live inventory confirmed cluster name drape, ALB host-header routing, and
all three RDS instances still present. See the
AWS system map.