API Gateway Custom Domain¶
Brings up apigw.{env}.tradai-system.com for the HTTP API. All-code after a one-time hosted-zone bootstrap.
What Pulumi owns¶
- ACM certificate (regional,
eu-central-1) forapigw.{env}.tradai-system.comwith SANapi.{env}.tradai-system.com. - Route 53 DNS validation records inside
{env}.tradai-system.com. aws.apigatewayv2.DomainName+ApiMapping(already wired ininfra/edge/modules/api_gateway.py).- Public A-alias
apigw.{env}.tradai-system.com→ API Gateway regional endpoint.
What Pulumi does NOT own¶
- The hosted zone
{env}.tradai-system.comitself. Looked up viaaws.route53.get_zone. Created once via the AWS CLI, NS records pasted into Squarespace once.
Prerequisites (per environment)¶
The hosted zone for {env}.tradai-system.com must exist in Route 53 and its 4 NS records must be live at the registrar (Squarespace) before pulumi up.
# 1. Create the zone (one-time, per env)
aws route53 create-hosted-zone \
--name {env}.tradai-system.com \
--caller-reference "$(date +%s)-{env}"
# 2. Grab the 4 NS values
aws route53 get-hosted-zone --id <ZONE_ID> --query 'DelegationSet.NameServers'
# 3. Paste into Squarespace
# DNS Settings → Custom Records → add 4 rows:
# Host: {env} Type: NS Data: <each NS value, one per row>
# 4. Verify propagation (expect the 4 AWS NS to appear)
dig +short NS {env}.tradai-system.com
Dev zone status: created 2026-06-22, ID Z00034421702TG3P6K259, NS propagation confirmed.
Deploy¶
Pulumi will:
- Request the ACM certificate (~30s).
- Write DNS validation records to the zone (~5s).
- Wait for ACM validation (~2-5min).
- Create the API Gateway custom DomainName + ApiMapping.
- Create the public A-alias.
Total: under 10 minutes from cold.
Verify¶
# DNS resolves
dig +short apigw.{env}.tradai-system.com
# Public TLS handshake + health
curl -fsS https://apigw.{env}.tradai-system.com/api/v1/health
# Protected paths need an M2M Bearer:
curl -fsS -H "Authorization: Bearer ${M2M_TOKEN}" \
https://apigw.{env}.tradai-system.com/api/v1/jobs
Rollback¶
Flip the flag off and redeploy:
pulumi config set --stack {env} api_gateway:enable_custom_domain false --cwd infra/edge
just infra-up-edge {env}
Pulumi tears down (in order): A-alias, ApiMapping, DomainName, CertificateValidation, validation records, Certificate. The hosted zone and the frontend's existing api-{env}.tradai-system.com CNAME (on the apex zone → ALB) are untouched throughout — traffic falls back transparently.
Prod bootstrap checklist¶
When prod is ready:
aws route53 create-hosted-zone --name prod.tradai-system.com --caller-reference "$(date +%s)-prod"(run withAWS_PROFILE=tradai).- Capture the 4 NS values from the response.
- Squarespace → DNS Settings → Custom Records → 4 rows, host
prod, typeNS, one value per row. - Wait for propagation:
dig +short NS prod.tradai-system.comreturns the 4 AWS NS. - Edit
infra/edge/Pulumi.prod.yaml: uncommentapi_gateway:enable_custom_domain: "true". just infra-up-edge prod.- Verify with the curl commands above (substituting
prod).