>_
EngineeringNotes
Module 05

Frontends Deployment to AWS

Hosting static frontends with S3 Object Storage and CloudFront CDN for global scale.

01

Core Concepts

In modern cloud architecture, you don't run a server (like Nginx on EC2) to serve static client-side applications (React, Next.js static exports, HTML/CSS). Instead, we use serverless hosting and caching to minimize cost and maximize scalability.

🪣

1. Object Stores (S3)

Storage

Simple Storage Service (S3) stores files as "objects" rather than hierarchical directories. We upload our frontend builds (`index.html`, JavaScript bundles, CSS, assets) here. S3 serves them reliably without any server management.

Learn S3 role
🌐

2. CDNs (CloudFront)

Distribution & CDN

A Content Delivery Network (CDN) caches static files at Edge Locations scattered across the globe. Instead of querying S3 in a distant region, users get assets served directly from the nearest physical server, saving latency and bandwidth.

Learn CloudFront role
02

Step 1: Sign up and get an AWS account

Before deploying anything, you need an active AWS account. Signup is simple but does require a valid credit/debit card for verification.

03

Step 2: Check S3 & CloudFront Access

Ensure your user has access to S3 and CloudFront. If you signed up as the root user (the email used to create the account), this access is granted automatically.

Interactive AWS Console MockupClick/Hover glowing S3 or CloudFront
aws
🔔⚙️Mumbai (ap-south-1)RU

Console HomeInfo

Recently visitedInfo
🌐Route 53
🖥️EC2
☸️Elastic Kubernetes Service
🔑IAM
📦Elastic Container Service
📂EFS
Pointers ➔🪣S3
Pointers ➔🌐CloudFront
🌱Elastic Beanstalk
🎥MediaStore
View all services
Applications (0)Info
RegionAsia Pacific (Mumbai)
ap-south-1 (Current Region)
NameDescriptionRegionAccount
No applicationsGet started by creating an application.
💡

How to use S3 & CloudFront inside the AWS Console: Under the "Recently Visited" pane, typing S3 or CloudFront in the main search bar opens the direct dashboard. S3 is used to host your code while CloudFront links your domain to S3.

04

Step 4: Build your React frontend

Before launching to AWS S3, you need to compile your modern client-side codebase (JSX, TSX, modern JavaScript) into standard, static files that web browsers can natively parse.

💡
Important Constraint

This approach will not work for frameworks that use live Server-Side Rendering (SSR) like Next.js. Static S3 hosting works for basic React apps (Vite/CRA), HTML/CSS/JS apps, Vue, Angular, and Static exports.

1. Go to your react project

Terminal
bash
cd /link/to/your/react/project

2. Build your project

This compiles your application and produces a static production bundle (usually inside a dist/ or build/ directory).

Terminal
bash
npm run build

3. Try serving the HTML/CSS/JS locally

Always verify your production build works locally before uploading it to AWS.

Terminal
bash
# Install static server globally
npm i -g serve

# Serve the static build folder (first go to dist/ or build/ folder and then run this command)
serve

At this point, you have basic static HTML/CSS/JS code that you can deploy on the internet. You might be tempted to host this on an EC2 instance, but that is not the right approach. Let's understand why a CDN is a much better choice.

You can even delete your react application from your local system now and just keep the production build folder because all the files are now uploaded to the S3 bucket and will be served through the CDN.

05

CSR vs. SSR: Why S3 Cannot Run Server-Side Rendering

To design proper cloud deployments, you must know how your web application executes code. The fundamental difference lies in wherethe HTML page is dynamically assembled: in the user's browser or on a remote server.

💻

CSR (Client-Side Rendering)

  • How it works: The server sends a nearly empty HTML page (`index.html`) containing a blank container (`
    `) and a link to a large JavaScript bundle.
  • Assembly: The browser downloads the JS bundle and executes it locally, dynamically creating the DOM and rendering the visual page in real time.
  • Hosting:Extremely simple. The server only hosts raw physical files. It doesn't do any processing. S3 and CloudFront are perfect for this.
⚙️

SSR (Server-Side Rendering)

  • How it works: When a user requests a page, a backend server runs code, fetches data from databases/APIs on-the-fly, and builds a fully completed HTML file.
  • Assembly: Assembled completely on the remote server for every single request. The browser receives a finished, crawlable page.
  • Hosting: Requires a constant running compute resource (like Node.js running on EC2, ECS, or Lambda) to execute code dynamically.

⚠️ Why S3 is Completely Incompatible with SSR

Amazon S3 (Simple Storage Service) is a pure Object Store. It works like a superpowered cloud hard drive. When S3 receives a web request, it finds the exact file (e.g., about.html or main.js) and sends it directly back.

S3 has absolutely NO CPU execution runtime or Node.js environment.

Because S3 has no server CPU runtime to execute code, it is physically incapable of running backend computations. It cannot run functions like Next.js Server Components, API routes (/api/users), or dynamic server-side database queries. If you try to upload a dynamic SSR project directly to S3, it will fail to compile or throw errors because there is no server to run it.

The Next.js Exception: Static Export

If you are using Next.js but still want to host on S3 to minimize cost, you can enable Static Exports. By adding output: 'export' inside your next.config.js, Next.js generates static HTML pages at build time. This converts your app into a Client-Side Rendered (CSR) site, making it perfectly compatible with S3!

06

Step 6: Content Delivery Networks (CDNs) & POPs

A CDN (Content Delivery Network) is a distributed group of servers deployed globally to accelerate web content delivery. Instead of routing every single global user to a single central machine (like an EC2 instance), we clone and distribute static assets to geographic caching points.

Global Traffic Simulator
🖥️ EC2 Server (USA)User (Europe)User (Asia)User (LatAm)160ms (Laggy)280ms (Very Slow)180ms (Delayed)

🔴 EC2 Machine Approach: Every request across the globe travels to the single origin VM. Slower, expensive, and subject to high packet loss over long geographical paths.

Core Terminology

📍 POP (Point of Presence)

A physical data center location housing CDN servers. AWS CloudFront operates hundreds of POPs around the world. These serve as local depots to deliver files instantly to adjacent cities.

⚡ Edge Servers & Caching

Edge servers are machines inside POPs that cache copy instances of your S3 files. The first user in Tokyo forces the Edge Server to download your code from S3 in USA. The next 10,000 users download it directly from the Tokyo cache.

🚫 Why Caching Does Not Work for Dynamic Backends

Object stores combined with CDNs are the gold standard for frontends, videos, and static images. However, you cannot cache dynamic backends the same way.

Every backend request returns a unique, context-aware database response.

Imagine a bank account endpoint `/api/balance`. If User A requests their balance, the server responds with $1,200. If the CDN Edge POP caches this response globally, then User B requesting `/api/balance` will receive the cached $1,200 page! This creates catastrophic security, transaction, and logic errors.

💡

Running Backends at the Edge: You can run API code closer to users on global edge runtimes (like AWS Lambda@Edge or fly.io). However, the raw data still cannot be cached in edge POPs universally because database mutations must remain dynamically consistent.

🏏
Learn in Production: Hotstar Scale-Up

Watch how CDNs scale live infrastructure for millions of simultaneous viewers.

Watch Video →
07

Step 7: Creating an Object Store in AWS

In AWS, S3 (Simple Storage Service) is the native object store. To store your files, you must create a Bucket—a logical folder or container dedicated to your specific project.

1

Open S3 Console & Click Create Bucket

Search for "S3" in the AWS search bar, click S3, and click the orange Create bucket button on the top right of the general purpose buckets grid.

2

Set Region & Globally Unique Name

Enter a Bucket name (e.g., shivam-test). S3 bucket names are sharing a global namespace, meaning no two AWS users in the world can have the exact same bucket name. Select your closest AWS Region.

3

Confirm Defaults & Create

Keep all default settings (Object Ownership: ACLs disabled, Block Public Access: Enabled) and click the orange Create bucket button at the very bottom. You will see a green success bar verifying the bucket has been launched!

08

Step 8: Upload the File Bundle to S3

Once S3 is created, you need to copy your local production bundle into the S3 bucket.

🪣
Crucial Step: Upload Contents, Not Folder

When uploading your React frontend, open your local dist/ or build/ directory. Select all the files inside it (the assets/ folder, index.html, and assets like vite.svg) and drag them directly into the S3 Object grid. Do NOT upload the parent dist folder itself, otherwise your index page will reside at /dist/index.html instead of the root /index.html.

Upload Methods:

🖱️ Drag & Drop

Simply select the files in your computer's Finder/Explorer window and drag them onto the S3 Console browser panel, then click the orange Upload button at the bottom.

💻 CLI (Continuous Delivery)

During automated CI/CD runs, you can sync files using a single AWS CLI command:

aws s3 sync dist/ s3://your-bucket-name
09

Step 9: Try Accessing the Website & The Security Trap

If you click on your uploaded index.html in the S3 dashboard and try to navigate to its direct object URL, you will be met with a cold XML error page:

https://shivam-test.s3.ap-south-1.amazonaws.com/index.htmlXML Viewer
<Error>
<Code>AccessDenied</Code>
<Message>Access Denied</Message>
<RequestId>T3YE0RGZZXH90J2W</RequestId>
<HostId>HGnIff+p0hpzxbx3flL99MWqAQn5Y5bVVN7hmLexMojiy9bk1wUCKqXDWUm3tuXCqI9fkli3jMQ=</HostId>
</Error>

🛑 The S3 Security Trap: Never Make Your Bucket Public!

When confronted with this error, many beginners will immediately Google a solution. You will find tutorials telling you to:

  1. Untoggle "Block all public access"
  2. Write a bucket policy that grants `s3:GetObject` permission to wildcard `*` public users.

DO NOT DO THIS! Making S3 buckets public is a major security vulnerability.

Making a bucket public leaves it exposed directly to the open internet. Attackers can scrape S3 endpoints, scrape index headers, search for secret logs, or bypass any CDN routing controls entirely. S3 is designed to hold assets securely and privately.

The Right Approach: S3 must remain completely private. We will configure CloudFront (our CDN) to act as a secure gatekeeper. CloudFront will access S3 using an OAC (Origin Access Control) policy, which authenticates requests between CloudFront and S3 under the hood. Users will only view files through the global CloudFront distribution URL, keeping S3 protected from direct access.

10

Step 10: Configuring CloudFront CDN

Now that your static bundle resides securely inside a private S3 bucket, it's time to set up the CloudFront Content Delivery Network (CDN). This handles SSL, global caching, custom domains, and acts as the gatekeeper to your files.

Interactive AWS CloudFront Creation WizardReplicating S3 OAC & WAF Setup
aws/CloudFront/Distributions/Create distribution
Console v2.0

Steps

1Get started
2Specify origin
3Enable security
4Review and create

Get started

Connect your websites, apps, files, or video streams to CloudFront. We optimize the performance, reliability, and security of your traffic.

Distribution options

Single website or appChoose if each website or application will have a unique configuration.
Multi-tenant architecture - NewChoose when you have multiple domains that need to share configurations.

Domain