Migrating adamcherrycomics.dangerouscentaur.com to a Shared Origin: DNS, CloudFront Routing, and Bucket Consolidation
What Was Done
We completed the migration of adamcherrycomics.dangerouscentaur.com from a per-site S3 bucket architecture to a shared-origin pattern. This involved:
- Fixing a DNS shadowing bug that broke www subdomain resolution
- Updating the Stripe checkout Lambda to work with current SDK versions
- Decommissioning the stale per-site S3 bucket
- Verifying all traffic routes correctly through the shared
dc-sitesbucket via CloudFront function-based routing
DNS Resolution: The RFC 1034 §4.3.3 Issue
The initial problem: www.adamcherrycomics.dangerouscentaur.com was returning NXDOMAIN despite a working wildcard *.dangerouscentaur.com CNAME at Namecheap.
Root cause: RFC 1034 Section 4.3.3 specifies that an explicit CNAME record at a label takes precedence over a wildcard at the parent. We had only configured the wildcard, so queries for the explicit www label weren't matching anything.
Solution: Added an explicit CNAME record at the adamcherrycomics label (the subdomain itself) pointing to the same CloudFront distribution endpoint:
adamcherrycomics.dangerouscentaur.com → dclu4nl5nln98.cloudfront.net (CNAME)
www.adamcherrycomics.dangerouscentaur.com → dclu4nl5nln98.cloudfront.net (CNAME)
Both now resolve to the shared CloudFront distribution E2Q4UU71SRNTMB, which handles all *.dangerouscentaur.com domains.
CloudFront Origin and Routing Architecture
Rather than maintain a separate S3 bucket per site, all dangerouscentaur.com sites now share a single origin:
- Origin:
dc-sites.s3.us-east-1.amazonaws.com - CloudFront Distribution:
E2Q4UU71SRNTMB - Routing logic: CloudFront Function
dc-sites-router
When a request arrives for adamcherrycomics.dangerouscentaur.com/index.html, the function rewrites the origin request URI to:
/adamcherrycomics.dangerouscentaur.com/index.html
This allows the S3 bucket to organize all sites in hostname-named prefixes while the CloudFront distribution presents a flat, per-hostname view to clients.
Decommissioning the Legacy Per-Site Bucket
After verifying that no traffic was being served from s3://adamcherrycomics.dangerouscentaur.com/, we confirmed it was safe to delete:
- Bucket state: 0 objects, 0 bytes
- Serving path verification: CloudFront origin is
dc-sites, not the hostname-named bucket - DNS dependency: CNAME points to CloudFront distribution, not S3 website endpoint
- Origin: Legacy bucket from the original per-site pattern predating the shared-bucket migration
Deletion was performed via AWS console. The bucket name remains globally unique to this account, so it could be recreated if needed (though no use case exists).
Stripe Checkout Lambda Update
The checkout Lambda was failing due to two SDK-related issues:
- Missing dependency:
typing_extensionsmodule not included in the deployment zip - Deprecated API:
ui_mode="embedded"was deprecated in stripe-python 15.1.0
Fix: Rebuilt the Lambda deployment zip to include typing_extensions and updated the checkout call to use ui_mode="hosted_page" instead. The frontend now correctly receives the Stripe session URL and redirects users to the hosted checkout page.
# Before (deprecated)
session = stripe.checkout.Session.create(
ui_mode="embedded",
...
)
# After (current)
session = stripe.checkout.Session.create(
ui_mode="hosted_page",
...
)
# Frontend redirect
window.location.href = session.url
HTML/CSS Updates
A dropdown hover positioning bug was fixed across all four site HTML pages by correcting the gap calculation in the navigation:
/* Before: inconsistent or missing gap */
.dropdown { top: calc(100% + 0px); }
/* After: consistent, testable gap */
.dropdown { top: calc(100% + 8px); }
Updated files:
/adamcherrycomics.dangerouscentaur.com/index.html/adamcherrycomics.dangerouscentaur.com/gallery.html/adamcherrycomics.dangerouscentaur.com/about.html/adamcherrycomics.dangerouscentaur.com/shop.html
Key Infrastructure Decisions
Why shared origin over per-site buckets?
- Cost: One S3 bucket + one CloudFront distribution for all
dangerouscentaur.comdomains reduces per-resource overhead - Operational simplicity: Single bucket to monitor, single distribution to invalidate, single routing layer to update
- Scalability: Adding new sites requires only uploading a new hostname-prefixed folder, no new AWS resources
- Performance: Shared cache pool across all sites (if desired for common assets); no multi-distribution latency
Why CloudFront Function for routing?
- Sub-millisecond latency: Functions execute at edge locations before the request reaches the origin
- No origin logic: S3 remains stateless; the function handles all hostname-to-path mapping
- Cost: CloudFront Functions charge per million invocations; far cheaper than Lambda@Edge for