
Let’s imagine we are building a MERN web application with a React frontend, Node.js/Express backend, database, file uploads, authentication, and thousands of users.
This is what the architecture could look like.
The Big Picture
USERS
│
▼
Route 53
│
▼
CloudFront
/ \
/ \
▼ ▼
S3 ALB
React Frontend │
▼
Auto Scaling
│
┌────────────┼────────────┐
▼ ▼ ▼
EC2 EC2 EC2
│ │ │
└────────────┼────────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
RDS ElastiCache SQS
Database Cache Queue
│ │
│ ▼
│ Worker
│
▼
S3
File Storage
At first, this diagram can look complicated.
But the important thing is that each service has a specific responsibility.
Instead of thinking about AWS as one giant system, think of it as a collection of specialized building blocks.
1. What Happens When You Open a Website?
Let's say a user types:
www.mywebsite.com
into their browser.
The request doesn't simply jump directly to an EC2 server.
It goes through several layers.
First, Route 53 helps the browser find where the domain should go. The request can then reach CloudFront, AWS's content delivery network.
CloudFront decides where the request should be served from.
If the user requests a React file such as JavaScript, CSS, or an image, CloudFront can retrieve it from Amazon S3.
If the request is something like:
GET /api/users
CloudFront can send it toward the backend through an Application Load Balancer (ALB).
So even before our backend receives the request, AWS has already handled DNS, content delivery, and traffic routing.
2. Route 53 — Finding Our Website
Amazon Route 53 is AWS's DNS service.
DNS is basically the system that translates a human-friendly domain name into a destination.
For example:
www.mywebsite.com
↓
DNS lookup
↓
CloudFront
Without DNS, users would need to remember an IP address instead of a domain name.
Route 53 therefore acts like the phone book of our website.
It doesn't run our frontend or backend. Its job is mainly to help users find the correct destination.
3. CloudFront — Bringing Content Closer to Users
Once Route 53 points the request toward CloudFront, CloudFront can handle the delivery of content.
CloudFront is a CDN (Content Delivery Network).
Imagine our application is hosted in a region far away from a user. Sending every image, JavaScript file, and CSS file all the way from our origin would add unnecessary latency.
CloudFront solves this by caching content at locations around the world called edge locations.
So a simplified flow looks like:
User
│
▼
CloudFront Edge Location
│
├── Cached content → Return immediately
│
└── Not cached → Ask the origin
This is especially useful for static content such as:
- React JavaScript files
- CSS
- Images
- Videos
- Documents
It can also sit in front of our API and work with services such as AWS WAF.
4. React Frontend — Where Users Interact
Our React application is the part users actually see.
The frontend contains things like:
Login page
Dashboard
Profile
Products
Buttons
Forms
Images
Because a React production build consists largely of static files, we don't necessarily need an EC2 server just to serve those files.
We can store the built frontend in Amazon S3.
For example:
React Project
│
▼
npm run build
│
▼
HTML + CSS + JS
│
▼
Amazon S3
│
▼
CloudFront
│
▼
Users
This is one of the first things that changed how I looked at AWS.
Not everything needs a traditional server.
5. Application Load Balancer — Sending Users to the Right Server
Now suppose the frontend calls our backend:
POST /api/login
GET /api/products
POST /api/orders
We don't want every user connecting directly to one EC2 instance.
Instead, requests can go through an Application Load Balancer (ALB).
ALB
│
┌──────────┼──────────┐
▼ ▼ ▼
EC2 EC2 EC2
The ALB distributes incoming requests across healthy backend instances.
It also performs health checks.
For example, if one EC2 instance stops responding:
EC2 #1 → Healthy
EC2 #2 → Healthy
EC2 #3 → Unhealthy
The ALB can stop sending new requests to the unhealthy instance.
This is much more reliable than depending on a single server.
6. EC2 + Auto Scaling — Running the Backend
Our Node.js and Express backend can run on Amazon EC2.
For example:
React
│
▼
API Request
│
▼
ALB
│
├── EC2 #1
├── EC2 #2
└── EC2 #3
But what happens when traffic suddenly increases?
This is where EC2 Auto Scaling becomes important.
During normal traffic:
2 EC2 instances
During heavy traffic:
4 EC2 instances
During extremely high traffic:
6 EC2 instances
The exact numbers depend on how we configure the scaling policy.
The important idea is that Auto Scaling adjusts computing capacity based on demand, while the ALB distributes traffic between the available instances.
These two services solve different problems:
| Service | Main Responsibility |
|---|---|
| ALB | Distributes requests |
| Auto Scaling | Adjusts number of EC2 instances |
| EC2 | Runs our application |
7. RDS — Where Our Application Data Lives
Our backend needs somewhere to store permanent data.
For example:
Users
Orders
Products
Payments
Messages
Profiles
This is where Amazon RDS can be used.
Instead of installing and maintaining a database manually on an EC2 server, RDS provides a managed relational database environment.
The backend might perform:
React
↓
ALB
↓
EC2
↓
RDS
For example, when a user creates an account:
User submits signup form
↓
React sends API request
↓
Backend receives request
↓
Backend validates data
↓
Backend writes user to RDS
The database should normally be placed in private subnets, rather than being directly exposed to the public internet.
8. S3 — Not Just for the Frontend
One thing that can easily confuse beginners is S3.
S3 is object storage.
It can store much more than React files.
Our application might allow users to upload:
Profile pictures
PDF files
Documents
Product images
Videos
Reports
Instead of putting these large files inside the database, we can store them in S3.
The database can then store information such as:
User ID
File name
S3 object key
Upload date
So we can think of it like:
RDS → Application data
S3 → Files / Objects
This separation makes the architecture easier to scale.
9. SQS — When Everything Doesn't Need to Happen Immediately
Some operations don't need to happen while the user is waiting.
Imagine a user uploads a video.
Our application might need to:
- Save the file
- Generate thumbnails
- Process the video
- Send an email
- Update another system
Doing everything inside the original request could make the application slow.
Instead, we can use Amazon SQS.
User
│
▼
Backend
│
▼
SQS Queue
│
▼
Worker
│
├── Process file
├── Send email
└── Perform background task
The backend can put a message into the queue and respond to the user.
A worker can process the job separately.
This creates decoupling between different parts of the system.
10. ElastiCache — Making Frequent Requests Faster
Not every piece of data needs to be fetched from the database every time.
Imagine thousands of users are requesting the same popular information.
Instead of repeatedly doing:
EC2 → RDS → Return data
we can cache frequently accessed data.
EC2
│
▼
ElastiCache
│
├── Data found → Return quickly
│
└── Data missing → Query RDS
ElastiCache can provide an in-memory cache using technologies such as Redis/Valkey or Memcached.
The important idea is:
Database = persistent source of data
Cache = fast temporary copy of frequently used data
Caching is an optimization, so it isn't required for every application.
11. Security — Protecting the Architecture
Now we have a working architecture, but putting everything on the internet would be a terrible idea.
Security needs to exist at multiple layers.
IAM
AWS IAM controls who or what can access AWS resources.
For example, instead of putting AWS access keys directly inside our Node.js code, we can give an EC2 instance an appropriate IAM role.
EC2
│
▼
IAM Role
│
▼
Allowed AWS Services
The application gets only the permissions it actually needs.
Security Groups
Security Groups act like virtual firewalls around AWS resources.
For example:
Internet
│
▼
ALB
│
▼
EC2
│
▼
RDS
We can configure rules such as:
Internet → ALB ✅
ALB → EC2 ✅
EC2 → RDS ✅
Internet → RDS ❌
This is much safer than exposing the database directly to the internet.
AWS WAF
AWS WAF protects web applications by inspecting incoming HTTP/HTTPS requests.
It can help block things such as malicious or unwanted web requests based on configured rules.
A simplified security flow becomes:
Internet
│
▼
WAF
│
▼
CloudFront
│
▼
ALB
│
▼
EC2
Secrets Manager
Our application also needs sensitive information such as:
Database password
API keys
Application secrets
These shouldn't simply be written directly inside source code.
AWS Secrets Manager provides a safer place to store and retrieve secrets.
12. VPC — The Network Behind Everything
All of these services don't just randomly exist on the internet.
Our backend architecture can be placed inside an Amazon VPC (Virtual Private Cloud).
A simple design could look like:
VPC
│
┌──────────┴──────────┐
│ │
Public Subnets Private Subnets
│ │
ALB EC2 / RDS / Cache
The public and private subnet design helps control which resources can be reached from the internet.
For a production architecture, we would normally distribute resources across multiple Availability Zones to improve availability.
13. Monitoring — Knowing What Is Happening
Building the infrastructure isn't enough.
We also need to know:
Is the application healthy?
Are servers running out of resources?
Are requests failing?
Is traffic increasing?
This is where Amazon CloudWatch becomes useful.
CloudWatch can provide metrics, logs, dashboards, and alarms.
For example:
CPU usage > threshold
↓
CloudWatch Alarm
↓
Auto Scaling / Notification
For auditing AWS API activity, CloudTrail records account and API activity.
So:
CloudWatch → Monitoring & Logs
CloudTrail → AWS Activity & Auditing
14. HTTPS — Encrypting Communication
When users access:
https://www.mywebsite.com
their communication should be encrypted.
AWS Certificate Manager (ACM) can provide and manage TLS certificates for supported AWS services.
So instead of sending sensitive information over plain HTTP, we use HTTPS.
This is especially important for:
- Login credentials
- Personal information
- Payments
- API requests
- Session information
15. Putting Everything Together
Now the individual services should make much more sense.
The complete request path can be summarized like this:
USER
│
▼
Route 53
│
▼
CloudFront
/ \
/ \
▼ ▼
S3 ALB
React Frontend │
▼
Auto Scaling
│
┌────────────┼────────────┐
▼ ▼ ▼
EC2 EC2 EC2
│ │ │
└────────────┼────────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
RDS ElastiCache SQS
Database Cache Queue
│ │
│ ▼
│ Worker
│
▼
S3
File Storage
And around this architecture we have:
IAM
Security Groups
WAF
Secrets Manager
ACM
CloudWatch
CloudTrail
VPC
These aren't just extra AWS services added to make the diagram look impressive.
Each one solves a different operational problem.
The Most Important Thing I Learned
When I first started learning AWS, I looked at services individually.
EC2 = Server
S3 = Storage
RDS = Database
Route 53 = DNS
CloudFront = CDN
That is useful for getting started.
But real cloud architecture is about understanding how those services work together.
A real application isn't just:
User → EC2
It is closer to:
User
↓
DNS
↓
CDN
↓
Load Balancer
↓
Application Servers
↓
Database / Cache / Queue / Storage
And surrounding all of that are networking, security, monitoring, and scaling mechanisms.
That's when AWS started making much more sense to me.
Quick Cheat Sheet
| Requirement | AWS Service |
|---|---|
| Domain / DNS | Route 53 |
| CDN | CloudFront |
| React static files | S3 |
| Backend | EC2 |
| Load balancing | ALB |
| Automatic scaling | Auto Scaling |
| Relational database | RDS |
| File storage | S3 |
| Background jobs | SQS |
| Caching | ElastiCache |
| Permissions | IAM |
| Network isolation | VPC |
| Firewall rules | Security Groups |
| Web protection | WAF |
| Secrets | Secrets Manager |
| HTTPS certificates | ACM |
| Monitoring | CloudWatch |
| AWS activity auditing | CloudTrail |
Final Thoughts
The biggest shift in my AWS learning wasn't memorizing more services.
It was learning to ask:
“What problem is this service solving, and where does it fit in the architecture?”
Once I started thinking that way, AWS stopped feeling like a huge list of unrelated services.
Instead, it started looking like a set of building blocks.
And when those building blocks are combined properly, we can build applications that are scalable, secure, highly available, and easier to operate.
That, for me, is where learning AWS started becoming much more interesting.
Top comments (0)