Skip to content

Teardown

Copilot edited this page Jul 11, 2026 · 1 revision

Teardown

Every piece of infrastructure nmailx creates can be deleted - no CloudFormation resource in this project uses a Retain deletion policy, so everything goes when the stack goes. This page expands on the README's Teardown section with a pre-teardown checklist and more detail on why the order matters.

Pre-teardown checklist

  • Export any data you need first. Deleting the main stack deletes all 5 DynamoDB tables - domains, users, templates, rate-limit counters, and send logs. If you need historical send logs or domain configuration for records, export them now:
    aws dynamodb scan --table-name <ProjectName>-SendLogEntries > send-logs-backup.json
    (repeat per table, substituting the actual table names from make outputs or the CloudFormation console).
  • Note whether you're using a custom domain (see Custom Domain Setup) - if so, you'll also need to tear down the separate bootstrap/custom-domain.yaml certificate stack and its Cloudflare CNAMEs.
  • Note whether OIDC/CI is set up - if you bootstrapped GitHub Actions OIDC deploys, decide whether you also want to remove that stack.

Teardown order

The order below matters: SES domain identities are runtime data created via boto3, not CloudFormation resources, so they aren't deleted automatically when the stack goes - and the script that cleans them up needs the DynamoDB Domains table to still exist so it knows which SES identities to remove. Do it in this order:

# 1. Clean up SES domain identities while the domains table still exists
make teardown-ses

# 2. Delete the main stack - deletes both Lambdas, the API, all 5 DynamoDB
#    tables (this deletes all domains/users/templates/log data - export first
#    with `aws dynamodb scan` if you need it), and the CloudWatch log groups
make delete-stack

#    (sam delete also offers to remove its own auto-managed S3 artifacts
#    bucket - say yes, or it's left behind as an empty orphaned bucket)

# 3. Optional: remove any Cloudflare DNS records you added
make cloudflare-dns-delete DOMAIN=<domain> ZONE_NAME=<zone> CF_API_TOKEN=<token>

# 4. Optional: if you used a custom domain, remove its Cloudflare CNAMEs
#    (the app.nmailx.com target and the ACM validation record), then delete
#    the certificate stack
make delete-domain-cert

# 5. Optional: if you're fully decommissioning CI/CD too
make delete-oidc-stack

Why make teardown-ses has to run first

scripts/teardown_ses.py is the reference example for the project's invariant that any resource creating runtime data outside CloudFormation's view (like SES identities via boto3) must have a matching teardown script. If you delete the main stack first, the Domains table (and the list of SES identities it implies) is gone, and you'd be left manually hunting through the SES console for orphaned identities to remove by hand.

What's NOT covered by this teardown sequence

  • The GitHub Pages landing page (docs/ + the www.nmailx.com DNS records) is independent of the AWS stack - see GitHub Pages and DNS if you ever want to remove that too (disable Pages in repo Settings, remove the Cloudflare CNAME and redirect rule).
  • The GitHub Wiki itself (this content) - wikis aren't part of the AWS teardown and have no infrastructure cost.

Clone this wiki locally