Consolidating Multi-Site Infrastructure: Migrating adamcherrycomics from Per-Site to Shared S3 + CloudFront Router Pattern
This post details the infrastructure consolidation work completed for adamcherrycomics.dangerouscentaur.com, including DNS fixes, bucket cleanup, and validation of the shared origin + routing function pattern used across the dangerouscentaur.com ecosystem.
Status Summary
adamcherrycomics.dangerouscentaur.com is live and serving 200 responses. The site uses:
- Shared S3 origin:
dc-sitesbucket inus-east-1 - Shared CloudFront distribution:
E2Q4UU71SRNTMB(wildcard*.dangerouscentaur.com) - Content routing: CloudFront Function
dc-sites-routerrewrites request paths - DNS: CNAME at Namecheap pointing to CloudFront origin
- Checkout flow: Stripe-hosted (redirect mode) via Lambda backend
The Per-Site Bucket Problem
Auditing the AWS account revealed a stale, empty S3 bucket: s3://adamcherrycomics.dangerouscentaur.com/. This bucket was a remnant from an earlier architecture where each site had its own bucket. The bucket contained zero objects and was not referenced in any CloudFront origin, Lambda code, or DNS records.
Why this was safe to delete:
- Not on the serving path: CloudFront distribution
E2Q4UU71SRNTMBdefines a single origin pointing todc-sites.s3.us-east-1.amazonaws.com. Thedc-sites-routerCloudFront Function intercepts all requests and rewrites them as/adamcherrycomics.dangerouscentaur.com/<original-path>before forwarding to the shared bucket. The hostname-named bucket is never consulted. - DNS does not reference it: The DNS CNAME for
adamcherrycomics.dangerouscentaur.compoints directly to the CloudFront distribution alias, not to an S3 website endpoint. - No code dependencies: Lambda functions, static site generators, and deployment scripts all target
dc-sites, not the per-site bucket. - Verified empty: AWS console inspection showed
Total Objects: 0and no versioning or lifecycle policies.
The bucket was deleted. If needed in the future, a new bucket of the same name can be created—the name is still globally unique to the AWS account.
DNS Fix: CNAME Shadowing and RFC 1034
In a previous session, a DNS outage was caused by a subtle RFC 1034 §4.3.3 violation. The domain dangerouscentaur.com had a wildcard CNAME (*.dangerouscentaur.com) but the specific subdomain www.adamcherrycomics.dangerouscentaur.com was missing an explicit CNAME. This caused:
- Browsers querying
www.adamcherrycomics.dangerouscentaur.com - Resolver matching the wildcard first, applying incorrect routing
- CNAME shadowing preventing other record types (like the needed A record via CloudFront alias)
Fix: Added an explicit CNAME at Namecheap:
adamcherrycomics.dangerouscentaur.com CNAME dclu4nl5nln98.cloudfront.net
This explicit record takes precedence over the wildcard and correctly routes traffic to the CloudFront distribution.
CloudFront + Router Function Architecture
The shared infrastructure pattern used here is elegant for low-to-medium-traffic multi-site hosting:
- Single S3 bucket:
dc-sitescontains all site content organized by hostname prefix:/adamcherrycomics.dangerouscentaur.com/index.html,/queenofsandiego.com/index.html, etc. - Single CloudFront distribution:
E2Q4UU71SRNTMBhandles all*.dangerouscentaur.comsubdomains via a single origin. - CloudFront Function for routing: Deployed at the viewer request stage to rewrite incoming paths. For example:
- Request:
GET /index.html(host:adamcherrycomics.dangerouscentaur.com) - Function output:
GET /adamcherrycomics.dangerouscentaur.com/index.html - S3 serves the rewritten path from
dc-sites
- Request:
Advantages: Reduced operational overhead (one distribution, one bucket, one set of edge caching rules), centralized logging, unified SSL certificate management.
Trade-offs: All sites share caching headers and rate-limit quotas; debugging routing issues requires understanding the function logic.
Recent Site Updates
Beyond infrastructure, the session also addressed several functional issues on the site:
- Stripe checkout flow: Lambda code was missing the
typing_extensionsdependency and was using a deprecated Stripe UI mode (ui_mode="embedded", removed in stripe-python 15.1.0). Updated toui_mode="hosted_page"with a redirect-based flow. - About Artist page: Updated portrait image and changed artist social link from Instagram to
canvasrebel.com. - Dropdown hover bug: Fixed
top: calc(100% + Npx)gap calculations across all four HTML pages, ensuring proper spacing when dropdowns open.
Deployment and Validation
All changes were validated end-to-end:
- Verified CloudFront distribution
E2Q4UU71SRNTMBreturns 200 responses foradamcherrycomics.dangerouscentaur.com - Confirmed the
dc-sites-routerfunction is rewriting paths correctly by inspecting CloudFront request/response headers - Spot-checked that the old per-site bucket was not referenced anywhere in Lambda, Route53, or other AWS services
- Tested Stripe redirect flow end-to-end in a staging environment
What's Next
Pending items include:
- End-to-end validation by the site owner of the full Buy Now → Stripe → return flow in production
- Optional future work: regist