Static Site With CloudFront And S3 — Quick Learn
A static site is a set of already-built files: HTML, CSS, JavaScript, images, and fonts. It does not need an application server to generate each response. The goal is to serve those files globally over HTTPS without making the storage bucket public.
The central design is simple:
Browser → Route 53 DNS answer → CloudFront → private S3 bucket
│
└─ returns an edge-cached copy on a hit
Route 53 helps the browser find CloudFront. CloudFront is the public entry point and cache. S3 is the private origin that stores the files.
What Happens On A Request
- Route 53 resolves the custom domain to CloudFront. DNS supplies an address; it does not carry or proxy the web request.
- The browser connects to CloudFront over HTTPS. An ACM certificate proves the site's identity. A certificate attached to CloudFront must be requested or imported in
us-east-1, even if the S3 bucket is elsewhere. - CloudFront checks its edge cache. A cache hit returns the stored object without contacting S3.
- On a cache miss, CloudFront requests the object from S3. Origin Access Control (OAC) signs that request. The bucket policy permits the intended CloudFront distribution, while S3 Block Public Access remains enabled.
- CloudFront caches the response and returns it. Later viewers near that edge can receive the cached copy faster.
OAC is an authorization mechanism between CloudFront and S3—not a separate network hop. A public website can therefore have a private bucket: users reach CloudFront, not S3 directly.
The Origin Choice Changes The Security Model
S3 exposes two interfaces that sound similar but behave differently.
Use the regular S3 bucket endpoint when CloudFront must use OAC to reach a private bucket. It supports HTTPS from CloudFront to S3.
The S3 static website endpoint supplies website behaviors such as index and error documents, but CloudFront treats it as a custom HTTP origin. It does not support OAC and the origin connection is HTTP. It is therefore the wrong choice when the requirement is a private S3 origin.
Read deeper about choosing the S3 origin interfaceCache The Files Without Serving Mixed Releases
CloudFront's cache improves latency and reduces origin requests, but deployments must account for objects already stored at the edge.
- Give versioned or content-hashed assets such as
app.a81f.jslong cache lifetimes. A changed file receives a new name, so old and new releases do not collide. - Give entry documents such as
index.htmla shorter cache lifetime, or invalidate their exact paths during a release. The entry document should discover the newest asset names quickly. - Use invalidations selectively. They remove cached copies of existing paths; they are not a substitute for versioned asset names.
For a single-page application, CloudFront's default root object solves /, not every nested route. A direct refresh of /orders/42 asks the origin for that path, but S3 may have no such object. A deliberate CloudFront rewrite or custom error response can return index.html, after which the client-side router renders the route.
SAA Recognition And Traps
- Global static assets, custom HTTPS domain, low operations → put CloudFront in front of S3. CloudFront supplies edge caching and the public HTTPS entry point; S3 durably stores the build output.
- Public site but private origin → use the regular S3 bucket endpoint with OAC and a restrictive bucket policy. Public users do not require a public bucket.
- CloudFront custom domain → the viewer certificate belongs in ACM in
us-east-1because CloudFront is a global service. - Users receive an old or mixed deployment → use immutable versioned assets and deliberately refresh the entry document.
- SPA works through in-app navigation but fails on refresh → the edge needs fallback or rewrite behavior for client-side routes.
Do not confuse DNS with content delivery, or OAC with encryption. Route 53 resolves the name; CloudFront serves and caches content; OAC authorizes CloudFront to read private S3 objects; HTTPS protects network traffic.
CloudFront also does not make oversized files small, hide secrets embedded in frontend code, or automatically justify AWS WAF. Those are separate design questions.
One-Minute Review
Built static files
↓
Private S3 bucket stores them
↓
CloudFront is the only public content entrance
↓
OAC + bucket policy authorize origin reads
↓
Route 53 supplies DNS; ACM supplies the viewer certificate
↓
Versioned assets + a refreshable entry document make releases cache-safe
If you remember only one thing: the website is public through CloudFront, while the S3 origin can remain private.