-
Notifications
You must be signed in to change notification settings - Fork 0
Custom Domain Setup
By default the stack is only reachable at its auto-generated
execute-api.<region>.amazonaws.com URL. This page covers serving both
/send and /admin from your own hostname instead (e.g. app.nmailx.com)
-
this is a different feature from the project's own marketing site,
which lives at
www.nmailx.comvia GitHub Pages (see GitHub Pages and DNS). The custom domain covered here is for your deployed API, not the project's landing page.
bootstrap/custom-domain.yaml is a deliberately isolated, one-time stack,
not part of the main template.yaml. API Gateway custom domains are an
already-approved service for this project, but ACM certificate issuance is
kept separate because DNS for this project lives in Cloudflare, not
Route53, and CloudFormation can't automate DNS validation against a
non-Route53 provider. Splitting it out means the main stack's day-to-day
deploys never block on an external DNS step.
make bootstrap-domain-cert DOMAIN_NAME=app.nmailx.com # blocks until DNS-validatedThis call blocks - ACM certificates stay CREATE_IN_PROGRESS until DNS
validation succeeds. While it's running, open a second terminal and run:
make bootstrap-domain-cert-validation-record DOMAIN_NAME=app.nmailx.com...to print the DNS validation CNAME (name + value). Add it in Cloudflare
DNS as DNS-only (not proxied) - a proxied record breaks ACM's
DNS-based validation, since Cloudflare's proxy intercepts the request
before it reaches the ACM validation checker. Once it propagates, ACM
validates automatically and the first command completes, printing the
stack's CertificateArn output. You can re-run
make bootstrap-domain-cert-validation-record any time afterward to fetch
the same value again.
Region requirement: bootstrap/custom-domain.yaml must be deployed in
the same AWS region as the main stack (us-east-1 by default) -
regional API Gateway custom domains require the certificate to live in
that same region, unlike CloudFront/edge-optimized domains, which always
use us-east-1 regardless of where the rest of the stack lives.
JWT_SIGNING_SECRET=... TURNSTILE_SECRET_KEY=... \
CUSTOM_DOMAIN_NAME=app.nmailx.com \
CUSTOM_DOMAIN_CERTIFICATE_ARN=<arn from step 1> \
make deploymake outputs will then show a CustomDomainTarget value (the API
Gateway-managed regional domain name). Add one more CNAME in Cloudflare DNS
pointing app.nmailx.com at that target - again, DNS-only, not proxied.
Once it propagates, both https://app.nmailx.com/send and
https://app.nmailx.com/admin work alongside the original execute-api
URL. Both remain live - the custom domain is an additional mapping, not
a replacement for the auto-generated one.
CustomDomainName and CustomDomainCertificateArn both default to empty,
which leaves default behavior completely unchanged: the custom domain
resources in template.yaml (an AWS::ApiGatewayV2::DomainName and an
AWS::ApiGatewayV2::ApiMapping, gated behind a HasCustomDomain
CloudFormation condition) are only created when both parameters are set.
See Teardown for the full sequence - in short,
make delete-domain-cert removes the bootstrap certificate stack, and you
should also remove the Cloudflare CNAMEs you added (the app.nmailx.com
target record and the ACM validation record) once the domain is no longer
in use.