Consolidating Multi-Site Infrastructure: CloudFront Routing, S3 Bucket Deduplication, and DNS CNAME Shadowing in the dangerouscentaur.com Ecosystem
What Was Done
During this session, we completed infrastructure cleanup and validation for adamcherrycomics.dangerouscentaur.com, a Stripe-integrated booking site operating within a shared multi-tenant CloudFront distribution. The work involved:
- Verified and deleted the stale per-site S3 bucket (
s3://adamcherrycomics.dangerouscentaur.com/) - Confirmed CloudFront origin architecture correctly routes through a shared bucket with intelligent rewrites
- Documented DNS architecture to clarify why the per-site bucket was safe to remove
- Validated that all live traffic is served by the consolidated infrastructure pattern
Technical Details: The Bucket Consolidation Pattern
The adamcherrycomics.dangerouscentaur.com domain originally followed a per-site bucket pattern common in early multi-tenant AWS deployments:
Old pattern:
├── s3://adamcherrycomics.dangerouscentaur.com/ [origin bucket]
│ └── index.html, assets/, ...
└── Route53: adamcherrycomics.dangerouscentaur.com → CloudFront dist
This pattern was later consolidated into a shared-bucket-with-routing model:
Current pattern:
├── s3://dc-sites/ [shared origin bucket]
│ ├── adamcherrycomics.dangerouscentaur.com/
│ ├── otherproject.dangerouscentaur.com/
│ └── ...
├── CloudFront distribution (ID: E2Q4UU71SRNTMB)
│ ├── Origin: dc-sites.s3.us-east-1.amazonaws.com
│ └── CloudFront Function (dc-sites-router)
│ └── Rewrites: /path → /adamcherrycomics.dangerouscentaur.com/path
└── Route53: adamcherrycomics.dangerouscentaur.com → CF dist CNAME
This consolidation provides several operational benefits: reduced bucket management overhead, unified versioning policies across sites, simpler IAM scoping (one bucket vs. N buckets), and centralized cache invalidation.
Why the Old Bucket Was Safe to Delete
Request path verification: The CloudFront distribution E2Q4UU71SRNTMB has exactly one origin configured: dc-sites.s3.us-east-1.amazonaws.com. All incoming requests to adamcherrycomics.dangerouscentaur.com are rewritten by the dc-sites-router CloudFront Function before reaching S3, transforming a request for /index.html into /adamcherrycomics.dangerouscentaur.com/index.html within the shared bucket.
DNS independence: The Route53 record for adamcherrycomics.dangerouscentaur.com is a CNAME pointing to dclu4nl5nln98.cloudfront.net (the CloudFront distribution edge), not to an S3 website endpoint. This means DNS resolution never touches the per-site bucket name, and removing the bucket has zero impact on domain resolution.
Bucket state verification: A direct S3 API call confirmed Total Objects: 0 — the bucket contained no content, versioning metadata, or access logs. The only resource cost was the monthly bucket fee (negligible) and organizational debt (higher).
# Verification command (no credentials shown):
aws s3api head-bucket --bucket adamcherrycomics.dangerouscentaur.com
aws s3api list-objects-v2 --bucket adamcherrycomics.dangerouscentaur.com
# Deletion:
aws s3api delete-bucket --bucket adamcherrycomics.dangerouscentaur.com
DNS CNAME Shadowing: A Brief Detour
This session also documented a DNS issue fixed in the prior deployment cycle (2026-05-21). The problem illustrates why explicit records matter in wildcard-heavy zones:
The wildcard record *.dangerouscentaur.com pointed to the shared CloudFront distribution. However, the www.adamcherrycomics CNAME was missing at Namecheap. This created a shadowing situation:
Zone: dangerouscentaur.com
├── *.dangerouscentaur.com CNAME → dclu4nl5nln98.cloudfront.net
└── Missing: adamcherrycomics.dangerouscentaur.com CNAME
Result: www.adamcherrycomics.dangerouscentaur.com resolved (matched wildcard)
adamcherrycomics.dangerouscentaur.com did NOT resolve (RFC 1034 §4.3.3)
RFC 1034 §4.3.3 rule: When a wildcard match occurs, a label-by-label search for a more specific CNAME stops if an intermediate node already has a CNAME record. Conversely, if a more specific CNAME exists, it takes precedence over the wildcard match.
Fix applied: Added explicit CNAME records at Namecheap for both adamcherrycomics and www.adamcherrycomics, pointing to the CloudFront edge. This ensures deterministic resolution regardless of wildcard shadowing, and makes the configuration self-documenting for future engineers.
Infrastructure Decisions: Shared Bucket + Router Function Pattern
Why consolidate? The per-bucket pattern (one S3 bucket per site) scales administratively poorly. With even 5–10 projects, you accumulate:
- N IAM policies scoped to N buckets
- N bucket-level configurations (versioning, logging, lifecycle, encryption)
- N CloudFront origins in a single distribution (or N distributions)
- N DNS records, N SSL certificate SANs, N cache invalidation workflows
The shared-bucket-with-function approach: A single S3 bucket holds all site content, partitioned by hostname prefix. A CloudFront Function (lightweight, runs on every request) performs the URI rewrite. This provides:
- One origin configuration: Single S3 bucket endpoint, single set of cache behaviors
- Declarative routing: The router function is version-controlled and human-readable
- Efficient cache: CloudFront caches the rewritten request path, so
/adamcherrycomics.dangerouscentaur.com/index.htmlin CF cache is separate from/otherproject.dangerouscentaur.com/index.html - Cost efficiency: One bucket, one distribution, one set of CloudFront request fees
CloudFront Function vs. Lambda@Edge: We used a CloudFront Function (sub-millisecond latency, no cold starts) rather than Lambda@Edge (higher lat