Skip to content

Commit 2e13581

Browse files
committed
Initial commit: AWS VPC + ALB + private EC2 architecture lab
0 parents  commit 2e13581

File tree

3 files changed

+149
-0
lines changed

3 files changed

+149
-0
lines changed

README.md

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# AWS VPC + ALB + Private EC2 Lab (2-AZ Network Architecture)
2+
3+
This lab demonstrates a production-style AWS network like you’d design as a Solutions Architect:
4+
5+
- Custom **VPC**
6+
- **Public** and **private** subnets across **2 Availability Zones**
7+
- **Internet Gateway** and **NAT Gateway**
8+
- **Application Load Balancer (ALB)** in public subnets
9+
- **EC2 web servers** in private subnets
10+
- Layered **route tables** and **security groups**
11+
12+
> Traffic flow: **Client → ALB (public subnet) → EC2 (private subnet)**
13+
14+
I built this to deepen my understanding of AWS networking, high availability, and exam-style architectures for the AWS Solutions Architect Associate.
15+
16+
---
17+
18+
## High-Level Architecture
19+
20+
**Region:** `us-east-1` (N. Virginia)
21+
**VPC CIDR:** `10.0.0.0/16`
22+
23+
### Subnets
24+
25+
| Subnet name | Type | AZ | CIDR | Purpose |
26+
|------------|---------|-------------|---------------|---------------------------------|
27+
| `public-a` | Public | `us-east-1a` | `10.0.1.0/24` | ALB, NAT gateway |
28+
| `public-b` | Public | `us-east-1b` | `10.0.2.0/24` | ALB |
29+
| `private-a`| Private | `us-east-1a` | `10.0.11.0/24`| EC2 web server |
30+
| `private-b`| Private | `us-east-1b` | `10.0.12.0/24`| EC2 web server |
31+
32+
### Internet Connectivity
33+
34+
- **Internet Gateway (`sa-lab-igw`)**
35+
- Attached to the VPC
36+
- Public route table sends `0.0.0.0/0` → IGW
37+
38+
- **NAT Gateway (`sa-lab-nat-a`)**
39+
- Lives in `public-a`
40+
- Private route table sends `0.0.0.0/0` → NAT
41+
- Allows private EC2 instances to reach the internet **outbound only** (e.g., OS updates) while remaining non-public.
42+
43+
### Route Tables
44+
45+
- **Public Route Table (`sa-lab-public-rt`)**
46+
- Associated with `public-a`, `public-b`
47+
- Routes:
48+
- `10.0.0.0/16` → local
49+
- `0.0.0.0/0` → Internet Gateway
50+
51+
- **Private Route Table (`sa-lab-private-rt`)**
52+
- Associated with `private-a`, `private-b`
53+
- Routes:
54+
- `10.0.0.0/16` → local
55+
- `0.0.0.0/0` → NAT Gateway
56+
57+
### Compute & Load Balancing
58+
59+
- **EC2 Instances**
60+
- AMI: Amazon Linux
61+
- Type: `t2.micro`/`t3.micro`
62+
- Subnets:
63+
- `sa-lab-web-a` in `private-a`
64+
- `sa-lab-web-b` in `private-b`
65+
- **No public IPs**
66+
- Bootstrapped with a user data script to install Apache and serve a simple page:
67+
[`user-data/webserver.sh`](user-data/webserver.sh)
68+
69+
- **Application Load Balancer (`sa-lab-alb`)**
70+
- Scheme: Internet-facing
71+
- Subnets: `public-a`, `public-b`
72+
- Listener: HTTP :80 → Target group `sa-lab-tg-web`
73+
- Target type: **Instance**
74+
- Health checks: HTTP `/`
75+
76+
### Security Groups
77+
78+
- **ALB Security Group (`sa-lab-alb-sg`)**
79+
- Inbound:
80+
- HTTP 80 from `0.0.0.0/0` (internet) — for the lab
81+
- Outbound:
82+
- All traffic (default)
83+
84+
- **Web Server Security Group (`sa-lab-web-sg`)**
85+
- Inbound:
86+
- HTTP 80 **from `sa-lab-alb-sg` only**
87+
- Outbound:
88+
- All traffic (default)
89+
90+
This creates a proper layered security model:
91+
92+
- Internet can reach **only** the ALB
93+
- ALB can reach the web servers
94+
- Web servers are not directly reachable from the internet
95+
96+
---
97+
98+
## Build Steps (Summary)
99+
100+
I created everything using the AWS Console to really see how the pieces fit:
101+
102+
1. **VPC**
103+
- Created `sa-lab-vpc` with CIDR `10.0.0.0/16`
104+
105+
2. **Subnets**
106+
- Created two public and two private subnets across `us-east-1a` and `us-east-1b`
107+
108+
3. **Internet Gateway & NAT**
109+
- Created and attached `sa-lab-igw`
110+
- Created `sa-lab-nat-a` in `public-a` with an Elastic IP
111+
112+
4. **Route Tables**
113+
- Public RT: associated with public subnets, default route to IGW
114+
- Private RT: associated with private subnets, default route to NAT
115+
116+
5. **EC2 Instances in Private Subnets**
117+
- Launched `sa-lab-web-a` in `private-a` and `sa-lab-web-b` in `private-b`
118+
- Disabled public IPs
119+
- Added user data to install Apache and serve a simple HTML page
120+
121+
6. **Security Groups**
122+
- `sa-lab-alb-sg`: HTTP from internet
123+
- `sa-lab-web-sg`: HTTP only from `sa-lab-alb-sg`
124+
125+
7. **Target Group & ALB**
126+
- Created `sa-lab-tg-web` (instance target type, HTTP:80, health check `/`)
127+
- Registered both EC2 instances
128+
- Created ALB `sa-lab-alb` targeting `sa-lab-tg-web` and mapped it to `public-a` and `public-b`
129+
130+
---
131+
132+
## How to Test
133+
134+
1. Go to **EC2 → Load Balancers** in the AWS Console.
135+
2. Select `sa-lab-alb`.
136+
3. Copy the **DNS name**, e.g.:
137+
138+
```text
139+
sa-lab-alb-1234567890.us-east-1.elb.amazonaws.com

notes/commands.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Handy commands used in this lab
2+
3+
# Example curl test from your local machine (replace with your ALB DNS)
4+
curl http://sa-lab-alb-XXXXXXX.us-east-1.elb.amazonaws.com

user-data/webserver.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
yum update -y
3+
yum install -y httpd
4+
systemctl enable httpd
5+
systemctl start httpd
6+
echo "Hello from $(hostname) in private subnet!" > /var/www/html/index.html

0 commit comments

Comments
 (0)