Glow Grove — Static Site on AWS (S3 + CloudFront)

AWS S3CloudFrontRoute 53ACMCI/CD

Executive Summary

Objective: Launch a fast, reliable, and low-cost marketing site using serverless building blocks.

Outcome: Static site on Amazon S3, delivered globally via Amazon CloudFront, custom domain via Amazon Route 53, HTTPS via AWS Certificate Manager. Initial deploys are manual; GitHub Actions CI/CD is planned.

Role: Cloud/DevOps + Frontend
Stack: Next.js static export → S3 (origin), CloudFront (CDN), Route 53 (DNS), ACM (TLS)

Architecture

Glow Grove S3 + CloudFront architecture showing user requests flowing through Route 53 DNS, CloudFront CDN, ACM SSL, to S3 static hosting, with planned GitHub Actions CI/CD deployment
ComponentPurposeNotes
S3 (website endpoint)Hosts static assetsPublic website endpoint used for index/error behavior
CloudFrontEdge caching, TLS terminationBrotli/GZIP; cache policies per asset type
Route 53DNS (A/AAAA alias)Apex/root points to CloudFront distribution
ACM (us-east-1)TLS certificateRequired region for CloudFront; covers apex and www
GitHub Actions (planned)CI/CD pipelineBuild → export → s3 sync → CloudFront invalidation
Registrar is GoDaddy. Nameservers updated to Route 53's NS set during launch.

Why this design

  • Performance/cost: static hosting + CDN = sub-second loads at cents/month.
  • Simplicity: no servers to manage; clean rollback via static assets.
  • Scalability: CloudFront handles global delivery.

Implementation

Domain & DNS

  • Created Route 53 hosted zone for glow-grove.com.
  • Updated GoDaddy nameservers to Route 53 NS set (OTP flow).
  • Fixed early misrouting by changing apex A (alias) to the CloudFront distribution (not S3 URL).

TLS/HTTPS

  • Issued ACM certificate in us-east-1 and attached to CloudFront.
  • Enforced HTTPS at the edge.

Hosting & CDN

  • Deployed static build to S3 bucket (website endpoint).
  • CloudFront caches assets globally.
  • If/when SPA routing is added: map 403/404 → /index.html in CloudFront custom error responses.

Current deploy (manual)

# local build/export
npm run build && npm run export

# deploy to S3

aws s3 sync out/ s3://glow-grove.com/ --delete

# bust CDN cache

aws cloudfront create-invalidation --distribution-id <DIST_ID> --paths "/*"

Planned CI/CD (GitHub Actions)

Trigger on merge to main: install → build → export → s3 sync → invalidate.

Use GitHub OIDC → AWS IAM role (least privilege) or scoped user.

Decisions & Trade-offs

  • Static site (SSG) over dynamic: lowest ops/cost; trade-off = no server logic.
  • CloudFront CDN for latency & TLS at edge; requires cache-busting (hashed filenames).
  • S3 website endpoint origin: easy index/error behavior; if switching to private S3 + OAC, adjust origin and routing.

Challenges & Solutions

  • A-record target confusion → Corrected to CloudFront alias (not S3 URL).
  • Registrar verification friction → Completed OTP; confirmed NS propagation before ACM DNS validation.
  • Cache freshness risk → Plan to use content-hashed assets; invalidate /* only for major releases.
  • Deep links for SPA routes (anticipated) → CloudFront 403/404 → /index.html.

Operations & Monitoring

  • CloudFront metrics: requests, bytes, 4xx/5xx, cache hit ratio (CloudWatch).
  • Budgets/alerts for S3/CloudFront spend thresholds.
  • Uptime checks (UptimeRobot/StatusCake) for apex and www.

Results (initial)

  • Launched late Sep 2025 with S3 + CloudFront.
  • Snappy edge delivery; Lighthouse tuning planned (image optimization + headers).
  • Cost profile: low single-digit USD/month at current traffic.

Roadmap

  • Add CI/CD (GitHub Actions + OIDC).
  • Enable hashed assets and selective invalidations.
  • Publish CloudWatch dashboard and uptime badge.
  • Migrate to private S3 + OAC when SPA routing stabilizes.

© 2023 - 2026 AdventuringGhost. All rights reserved.

Built with Next.js, Tailwind CSS, and deployed on AWS S3 + CloudFront