00 · Big Picture
Cái nào chứa cái nào?
Trước tiên hãy xem sơ đồ tổng quan – đây là thứ bạn cần nhớ ngay cả khi quên hết mọi thứ khác.
🌏 AWS REGION (ap-southeast-1 · Singapore) Lớn nhất
├── 🔵 VPC – Virtual Private Cloud (10.0.0.0/16) Chứa tất cả dưới đây
│ ├── 🟢 Public Subnet (10.0.1.0/24) – AZ-a Có route → IGW
│ │ ├── 🖥 EC2 (Web Server) Có Public IP
│ │ ├── ⚖ ALB (Load Balancer)
│ │ └── 🔀 NAT Gateway Cho Private Subnet ra ngoài
│ │ └── 🛡 Security Group (gắn vào EC2/ALB) Firewall tầng instance
│ ├── 🟢 Public Subnet (10.0.2.0/24) – AZ-b
│ │ └── 🖥 EC2 (Web Server)
│ ├── 🔴 Private Subnet (10.0.11.0/24) – AZ-a Không có route → IGW
│ │ ├── 🗄 RDS (Database)
│ │ └── 🖥 EC2 (App Server)
│ │ └── 🛡 Security Group (chỉ cho Public Subnet vào)
│ └── 🔴 Private Subnet (10.0.12.0/24) – AZ-b
│ └── 🗄 RDS Replica
├── 🌐 Internet Gateway (IGW) Gắn vào VPC · 1 IGW / VPC
├── 🗺 Route Table (Public) → 0.0.0.0/0 via IGW
└── 🗺 Route Table (Private) → 0.0.0.0/0 via NAT GW
🌐
INTERNET
Users, external services, public APIs...
↕
🌏 AWS Region · ap-southeast-1
→ Cửa ngõ duy nhất giữa VPC và Internet
→ Gắn trực tiếp vào VPC (1 IGW / 1 VPC)
→ Stateful – không filter, chỉ route
↕
🔵 VPC · 10.0.0.0/16 · Khoảng 65,536 địa chỉ IP
📍 Availability Zone A
🟢 PUBLIC SUBNET · 10.0.1.0/24
Route: 0.0.0.0/0 → IGW · 10.0.0.0/16 → local
🔴 PRIVATE SUBNET · 10.0.11.0/24
Route: 0.0.0.0/0 → NAT GW · 10.0.0.0/16 → local
📍 Availability Zone B
🟢 PUBLIC SUBNET · 10.0.2.0/24
Route: 0.0.0.0/0 → IGW
🔴 PRIVATE SUBNET · 10.0.12.0/24
Route: 0.0.0.0/0 → NAT GW
🔑 Quy tắc nhớ nhanh
Region → chứa →
VPC → chứa →
Subnet → chứa →
EC2/RDS/... → gắn →
Security Group.
IGW gắn vào VPC.
NAT GW đặt trong Public Subnet, phục vụ Private Subnet.
Route Table quyết định subnet là Public hay Private.
01 · Lớp ngoài cùng
Region & Availability Zone
🌏
Region
Vùng địa lý độc lập. Mỗi Region gồm 2–6 AZ riêng biệt nhau vật lý nhưng kết nối tốc độ cao. Dữ liệu không tự chuyển giữa Region.
🏢
Availability Zone (AZ)
Một hoặc nhiều data center độc lập về điện, làm mát, vật lý. Thất bại AZ này không ảnh hưởng AZ khác. Dùng Multi-AZ để HA.
📡
Edge Location
Điểm hiện diện của CloudFront CDN. Không phải AZ – chỉ dùng để cache và phân phối nội dung gần người dùng hơn.
📍 Việt Nam nên chọn Region nào?
ap-southeast-1 (Singapore) – latency ~20–40ms từ Hà Nội/HCM, đầy đủ dịch vụ AWS.
ap-southeast-3 (Jakarta) – mới hơn, latency tương đương, một số dịch vụ chưa có.
02 · Mạng ảo riêng
VPC – Virtual Private Cloud
VPC là mạng ảo riêng tư của bạn trong AWS. Nó hoàn toàn bị cô lập với các account AWS khác và với Internet (trừ khi bạn chủ động mở). Hãy nghĩ VPC như một tòa nhà văn phòng riêng – bên trong có phòng ban, hành lang, quy tắc vào ra.
| Đặc điểm | Giá trị / Giới hạn | Ghi chú |
| CIDR block | /16 đến /28 | Thường dùng 10.0.0.0/16 (65,536 IP). Không thể thay đổi sau khi tạo. |
| VPC mặc định | 1 mỗi Region | AWS tạo sẵn, có thể xóa nhưng nên giữ cho lab/dev. |
| VPC tối đa | 5 mỗi Region (soft limit) | Có thể tăng bằng cách request AWS. |
| Tenancy | Default hoặc Dedicated | Dedicated = chạy trên phần cứng riêng, giá cao hơn. |
| DNS | enableDnsSupport + enableDnsHostnames | Bật cả hai để instance nhận hostname DNS tự động. |
VPC Peering & VPC Endpoints
🔗 VPC Peering
- Kết nối 2 VPC với nhau (cùng hoặc khác account, khác Region)
- Traffic đi qua private AWS network, không qua Internet
- Không transitive: A↔B, B↔C ≠ A↔C
- CIDR 2 VPC không được overlap
🎯 VPC Endpoint
- Truy cập AWS services (S3, DynamoDB...) từ Private Subnet mà không cần NAT
- Gateway Endpoint: S3 và DynamoDB (miễn phí)
- Interface Endpoint: 150+ AWS services (có phí)
- Traffic không ra Internet – bảo mật và nhanh hơn
03 · Phân vùng trong VPC
Subnet – Phân đoạn mạng
Subnet là phân đoạn của VPC, nằm trong một AZ cụ thể. Điều làm subnet trở thành Public hay Private là Route Table – không phải tên gọi hay bất kỳ thuộc tính nào khác.
🟢 Public Subnet
- Route Table có entry:
0.0.0.0/0 → IGW
- Instance CÓ THỂ có Public IP hoặc Elastic IP
- Traffic từ Internet có thể vào (nếu SG cho phép)
- Dùng cho: Web server, ALB, Bastion host, NAT GW
- Ví dụ CIDR: 10.0.1.0/24 (254 IP dùng được)
🔴 Private Subnet
- Route Table KHÔNG có entry đến IGW
- Instance chỉ có Private IP, không có Public IP
- Internet không thể chủ động kết nối vào
- Dùng cho: Database, App server, Lambda, ElastiCache
- Ra ngoài Internet được qua NAT Gateway (1 chiều)
⚠️ AWS giữ lại 5 IP đầu mỗi subnet
Subnet
10.0.1.0/24 có 256 địa chỉ nhưng chỉ dùng được 251:
.0 Network address ·
.1 VPC Router ·
.2 DNS ·
.3 Reserved tương lai ·
.255 Broadcast
Thiết kế subnet phổ biến (3-tier architecture)
| Tier | Subnet | Thành phần | CIDR ví dụ |
| Web Tier | Public | ALB, Web server (EC2), NAT GW | 10.0.1.0/24, 10.0.2.0/24 |
| App Tier | Private | App server (EC2), Lambda, ECS | 10.0.11.0/24, 10.0.12.0/24 |
| Data Tier | Private | RDS, ElastiCache, DynamoDB | 10.0.21.0/24, 10.0.22.0/24 |
04 · Bộ định tuyến
Route Table – Bảng định tuyến
Route Table là tập hợp các rules định tuyến traffic từ subnet đến đích. Mỗi subnet phải được liên kết với đúng một Route Table. Đây là thứ quyết định subnet có "nhìn thấy" Internet không.
| Destination | Target | Ý nghĩa | Loại Route Table |
10.0.0.0/16 | local | Traffic trong VPC → đi nội bộ. Mọi Route Table đều có rule này, không xóa được. | Tất cả |
0.0.0.0/0 | igw-xxxxxxxx | Mọi traffic ra ngoài → qua Internet Gateway | Public |
0.0.0.0/0 | nat-xxxxxxxx | Mọi traffic ra ngoài → qua NAT Gateway (trong Public Subnet) | Private |
10.1.0.0/16 | pcx-xxxxxxxx | Traffic đến VPC được peer → qua VPC Peering connection | Khi có Peering |
pl-xxxxxxxx | vpce-xxxxxxxx | Traffic đến S3/DynamoDB → qua VPC Endpoint (không qua Internet) | Khi có Endpoint |
💡 Longest Prefix Match
Router luôn chọn route
cụ thể nhất (prefix dài nhất). Ví dụ:
10.0.1.5 sẽ match
10.0.1.0/24 thay vì
10.0.0.0/16, dù cả hai đều match.
05 · Cửa ngõ Internet
Internet Gateway (IGW)
IGW là cầu nối duy nhất giữa VPC và Internet. Không có IGW = không có gì trong VPC tiếp cận Internet được (kể cả EC2 trong Public Subnet). Ngược lại, không có IGW = Internet cũng không gọi vào được.
🔁
Horizontally Scaled
IGW có khả năng co giãn ngang tự động, không có bandwidth bottleneck. Bạn không cần lo về capacity.
🗺
NAT cho Public IP
IGW thực hiện 1:1 NAT giữa Private IP và Public IP của instance. Nó biết "EC2 10.0.1.5 có Public IP 54.x.x.x" và map qua lại.
1️⃣
1 IGW / 1 VPC
Mỗi VPC chỉ gắn được 1 IGW. Gắn IGW vào VPC chưa đủ – phải thêm route trong Route Table của subnet mới có effect.
🔗
Stateful (kiểu)
IGW không filter traffic. Nó chỉ route. Việc filter là của Security Group và NACL. IGW chỉ là "cửa" – SG/NACL mới là "bảo vệ".
06 · Private → Internet (1 chiều)
NAT Gateway
NAT Gateway cho phép instance trong Private Subnet khởi tạo kết nối ra Internet (download update, gọi API bên ngoài...) mà không để Internet gọi ngược vào. Đây là cơ chế một chiều hoàn hảo cho các resource nhạy cảm như database.
🗄
EC2 / RDS trong Private Subnet
10.0.11.5 (chỉ có Private IP)
Muốn tải package từ Internet
↑ Request ra
🔀 NAT Gateway
(trong Public Subnet)
Elastic IP: 54.x.x.x
↑ Đổi source IP thành 54.x.x.x
↕
↓ Response về
🌐 Internet Gateway
🌐
Internet / External Server
Chỉ thấy IP của NAT GW
Không biết Private Subnet tồn tại
Không thể initiate kết nối ngược vào
⚠️ NAT GW không miễn phí
NAT Gateway tốn phí theo 2 chiều:
giờ hoạt động (~$0.045/giờ) +
data processed ($0.045/GB). Đây thường là chi phí ẩn lớn nhất trong AWS bill. Mỗi AZ nên có NAT GW riêng để tránh cross-AZ traffic (cũng tốn tiền).
NAT Gateway vs NAT Instance
| Tiêu chí | NAT Gateway (Managed) | NAT Instance (EC2) |
| Quản lý | AWS fully managed | Tự quản lý OS, patch, HA |
| Bandwidth | Đến 100 Gbps (tự scale) | Giới hạn bởi instance type |
| HA | Tự động trong AZ | Cần tự cấu hình failover |
| Chi phí | Cao hơn | Thấp hơn nhưng ops overhead |
| Security Group | Không thể gắn SG trực tiếp | Có thể gắn SG |
| Bastion Host | Không thể dùng làm bastion | Có thể dùng làm cả bastion |
| Khuyến nghị | Production | Dev/test để tiết kiệm |
07 · Firewall tầng Instance
Security Group
Security Group là firewall ảo gắn trực tiếp vào instance (EC2, RDS, Lambda, ALB...). Nó kiểm soát traffic vào/ra ở tầng instance, không phải tầng subnet. Một instance có thể gắn nhiều SG; một SG có thể gắn vào nhiều instance.
🔄
Stateful
Nếu cho phép traffic vào, response traffic tự động được phép ra (và ngược lại). Không cần viết rule cả 2 chiều.
✅
Allow-only
Security Group chỉ có rules ALLOW. Không có deny rules. Mọi traffic không match bất kỳ allow rule nào đều bị drop ngầm.
🔗
Reference SG khác
Source/Destination có thể là một SG khác, không chỉ là IP. Ví dụ: "Chỉ cho SG-web vào port 3306" – cực kỳ mạnh cho internal traffic.
🔀
Gắn linh hoạt
Có thể thêm/bớt SG vào instance đang chạy mà không cần restart. Rules thay đổi có hiệu lực ngay lập tức.
⬇ INBOUND RULES (traffic vào instance)
Port 443 TCP
Source: 0.0.0.0/0 (mọi IP)
Cho phép HTTPS từ Internet vào
Port 80 TCP
Source: 0.0.0.0/0
HTTP – nên redirect sang 443
Port 22 TCP
Source: 203.0.113.10/32 (IP văn phòng)
SSH – chỉ từ IP tin cậy
Port 8080 TCP
Source: sg-alb (SG của ALB)
App port – chỉ ALB mới gọi được
⬆ OUTBOUND RULES (traffic ra từ instance)
All traffic All
Destination: 0.0.0.0/0
Default rule – cho phép mọi traffic ra ngoài
→ Trong thực tế production, nên restrict outbound:
Port 3306 TCP
Destination: sg-database
Chỉ kết nối MySQL đến DB
Port 443 TCP
Destination: 0.0.0.0/0
Gọi external HTTPS APIs
💡 Best Practice: Chain Security Groups
Thay vì mở IP cụ thể, hãy reference SG:
→ ALB SG: allow 443 from 0.0.0.0/0
→ EC2 SG: allow 8080 from
sg-alb (chỉ ALB mới vào được)
→ RDS SG: allow 3306 from
sg-ec2 (chỉ EC2 mới vào được)
Kết quả: database hoàn toàn không thể reach từ Internet dù không có Firewall rule "deny".
08 · Hướng traffic
Inbound & Outbound
Inbound và Outbound là hướng nhìn từ instance – không phải từ user hay từ Internet.
⬇ INBOUND (Traffic đi VÀO instance)
- User gọi vào web server của bạn → Inbound port 443
- ALB forward request đến EC2 → Inbound port 8080
- EC2 kết nối vào RDS → Inbound port 3306 (nhìn từ RDS)
- Admin SSH vào EC2 → Inbound port 22
- Mặc định: tất cả bị chặn nếu không có allow rule
⬆ OUTBOUND (Traffic đi RA từ instance)
- EC2 gọi API bên ngoài → Outbound port 443
- EC2 download package → Outbound port 80/443
- EC2 kết nối vào RDS → Outbound port 3306 (nhìn từ EC2)
- Response trả về user (stateful, tự động) → Không cần outbound rule
- Mặc định: tất cả được phép (default SG allow all outbound)
Ví dụ thực tế: User mở website của bạn
📡 Luồng traffic: HTTPS request từ User đến EC2
🌐 User
1.2.3.4
→
🌐 IGW
Nhận packet
→
🗺 Route Table
0.0.0.0/0 → local?
→
🛡 Security Group
Check Inbound
→
🖥 EC2
10.0.1.5
↑ Port 443 allowed? Nếu YES → vào. Nếu NO → drop silently
🖥 EC2
Response
→
🛡 SG Stateful
Auto-allow response
→
🌐 IGW
NAT: 10.0.1.5 → 54.x
→
🌐 User
Nhận response
↑ Vì SG stateful, không cần outbound rule cho port 443 response
Ví dụ: Private Subnet EC2 gọi ra Internet (qua NAT)
📡 Luồng traffic: Private EC2 download update
🖥 Private EC2
10.0.11.5
→
🗺 Private RT
0.0.0.0/0 → NAT
→
🔀 NAT GW
Public Subnet
→
🌐 IGW
→
🌐 Internet
Package server
🌐 Internet
Response
→
🌐 IGW
→
🔀 NAT GW
Translate ngược lại
→
🖥 Private EC2
Nhận packages
Internet chỉ thấy IP của NAT GW. Không thể initiate kết nối ngược vào Private EC2.
09 · Firewall tầng Subnet
Network ACL (NACL)
NACL là firewall ở tầng subnet, kiểm tra mọi traffic vào/ra subnet. Trong khi Security Group gắn vào instance, NACL gắn vào subnet – tất cả traffic qua subnet đều bị kiểm tra.
🛡 Security Group vs 🔒 NACL
- SG: Gắn vào instance · NACL: Gắn vào subnet
- SG: Stateful · NACL: Stateless (phải viết rule cả 2 chiều)
- SG: Chỉ Allow · NACL: Allow VÀ Deny (có thể block IP cụ thể)
- SG: Đánh giá tất cả rules · NACL: Đánh giá theo số thứ tự (100, 200...) và dừng khi match
- SG: Chặn traffic giữa instances cùng SG · NACL: Không thể phân biệt instances trong subnet
🔒 Khi nào dùng NACL?
- Block IP cụ thể đang tấn công DDoS → NACL Deny rule
- Chặn traffic từ một country range (IP block)
- Defense in depth: thêm tầng kiểm soát ngoài SG
- Compliance yêu cầu subnet-level firewall
- Thực tế: hầu hết project chỉ dùng SG là đủ
⚠️ NACL Stateless – Phải nhớ Ephemeral Ports
Vì NACL stateless, response traffic từ EC2 ra ngoài dùng
ephemeral ports (1024–65535). Nếu dùng NACL, inbound rule phải allow 443 vào; outbound rule phải allow 1024–65535 ra (cho response). Quên cái này là mất kết nối.
10 · Tổng hợp
Traffic Flow – Kiểm tra từng lớp
Khi troubleshoot network issue trong AWS, hãy đi theo đúng thứ tự các lớp kiểm tra này:
| Thứ tự | Lớp kiểm tra | Câu hỏi cần hỏi | Fix nếu sai |
| 1 |
🌐 IGW |
VPC đã có IGW gắn chưa? |
Tạo và attach IGW vào VPC |
| 2 |
🗺 Route Table |
Subnet có route 0.0.0.0/0 → IGW (Public) hoặc → NAT (Private) không? |
Thêm route entry vào Route Table, associate với subnet |
| 3 |
🔒 NACL |
NACL của subnet có allow traffic không? (Check cả inbound lẫn outbound vì stateless) |
Thêm NACL allow rules, nhớ cả ephemeral ports |
| 4 |
🛡 Security Group |
SG gắn vào instance có inbound rule cho port đó không? |
Thêm inbound rule vào SG |
| 5 |
🌐 Public IP |
Instance có Public IP hoặc Elastic IP không? (Với Public Subnet) |
Bật "Auto-assign Public IP" hoặc gắn Elastic IP |
| 6 |
🖥 OS Firewall |
iptables / Windows Firewall trên instance có block không? |
Kiểm tra và mở trong OS-level firewall |
| 7 |
🔧 Application |
App có đang listen trên đúng port không? (netstat -tlnp) |
Kiểm tra config app, restart service |
11 · Bảng tổng hợp
So sánh tất cả thành phần
| Thành phần | Cấp độ | Scope | Stateful? | Allow / Deny | Ghi chú chính |
| Region |
🌏 Địa lý |
Chứa tất cả |
— |
— |
Dữ liệu không tự chuyển giữa Region |
| VPC |
🔵 Mạng |
Trong Region |
— |
— |
Isolated network, CIDR /16–/28 |
| Subnet |
📦 Phân đoạn |
Trong VPC, 1 AZ |
— |
— |
Public/Private phụ thuộc Route Table |
| Route Table |
🗺 Định tuyến |
Gắn vào Subnet |
— |
— |
Quyết định traffic đi đâu |
| Internet Gateway |
🌐 Cửa ngõ |
Gắn vào VPC |
— |
— |
1 IGW / 1 VPC, không filter |
| NAT Gateway |
🔀 Dịch địa chỉ |
Trong Public Subnet |
✅ Yes |
— |
Private → Internet 1 chiều, có phí |
| NACL |
🔒 Firewall |
Tầng Subnet |
❌ No |
Allow + Deny |
Stateless, check theo số thứ tự rule |
| Security Group |
🛡 Firewall |
Tầng Instance |
✅ Yes |
Allow only |
Có thể reference SG khác làm source |
12 · Thực hành
Tạo VPC chuẩn production bằng CLI
aws-cli · Tạo VPC + Subnet + IGW + NAT + SG
# ══ 1. TẠO VPC ══════════════════════════════════════
VPC_ID=$(aws ec2 create-vpc \
--cidr-block 10.0.0.0/16 \
--tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=prod-vpc}]' \
--query 'Vpc.VpcId' --output text)
# Bật DNS hostname cho VPC
aws ec2 modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-hostnames
# ══ 2. TẠO INTERNET GATEWAY & ATTACH VÀO VPC ═══════
IGW_ID=$(aws ec2 create-internet-gateway \
--query 'InternetGateway.InternetGatewayId' --output text)
aws ec2 attach-internet-gateway --internet-gateway-id $IGW_ID --vpc-id $VPC_ID
# ══ 3. TẠO SUBNETS ══════════════════════════════════
# Public Subnet AZ-a
PUB_A=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.1.0/24 \
--availability-zone ap-southeast-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-1a}]' \
--query 'Subnet.SubnetId' --output text)
# Bật auto-assign Public IP cho Public Subnet
aws ec2 modify-subnet-attribute --subnet-id $PUB_A --map-public-ip-on-launch
# Private Subnet AZ-a
PRIV_A=$(aws ec2 create-subnet \
--vpc-id $VPC_ID \
--cidr-block 10.0.11.0/24 \
--availability-zone ap-southeast-1a \
--tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-1a}]' \
--query 'Subnet.SubnetId' --output text)
# ══ 4. ROUTE TABLE CHO PUBLIC SUBNET ════════════════
PUB_RT=$(aws ec2 create-route-table --vpc-id $VPC_ID \
--query 'RouteTable.RouteTableId' --output text)
# Thêm route đến IGW
aws ec2 create-route --route-table-id $PUB_RT \
--destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID
# Associate với Public Subnet
aws ec2 associate-route-table --route-table-id $PUB_RT --subnet-id $PUB_A
# ══ 5. NAT GATEWAY (đặt trong Public Subnet) ════════
EIP=$(aws ec2 allocate-address --domain vpc \
--query 'AllocationId' --output text)
NAT_ID=$(aws ec2 create-nat-gateway \
--subnet-id $PUB_A \
--allocation-id $EIP \
--query 'NatGateway.NatGatewayId' --output text)
echo "Đợi NAT Gateway available..."
aws ec2 wait nat-gateway-available --nat-gateway-ids $NAT_ID
# ══ 6. ROUTE TABLE CHO PRIVATE SUBNET ═══════════════
PRIV_RT=$(aws ec2 create-route-table --vpc-id $VPC_ID \
--query 'RouteTable.RouteTableId' --output text)
aws ec2 create-route --route-table-id $PRIV_RT \
--destination-cidr-block 0.0.0.0/0 --nat-gateway-id $NAT_ID
aws ec2 associate-route-table --route-table-id $PRIV_RT --subnet-id $PRIV_A
# ══ 7. SECURITY GROUP CHO WEB SERVER ════════════════
SG_WEB=$(aws ec2 create-security-group \
--group-name sg-webserver \
--description "Web Server SG" \
--vpc-id $VPC_ID \
--query 'GroupId' --output text)
# Inbound: HTTPS từ mọi nơi
aws ec2 authorize-security-group-ingress \
--group-id $SG_WEB --protocol tcp --port 443 --cidr 0.0.0.0/0
# Inbound: SSH chỉ từ IP văn phòng
aws ec2 authorize-security-group-ingress \
--group-id $SG_WEB --protocol tcp --port 22 --cidr 203.0.113.10/32
# ══ 8. SECURITY GROUP CHO DATABASE ══════════════════
SG_DB=$(aws ec2 create-security-group \
--group-name sg-database \
--description "Database SG – only from web" \
--vpc-id $VPC_ID \
--query 'GroupId' --output text)
# Inbound: MySQL chỉ từ Web Server SG (reference SG!)
aws ec2 authorize-security-group-ingress \
--group-id $SG_DB --protocol tcp --port 3306 \
--source-group $SG_WEB
echo "✅ VPC production đã sẵn sàng!"
echo "VPC: $VPC_ID | Public Subnet: $PUB_A | Private Subnet: $PRIV_A"
✅ Kiểm tra kết quả
Sau khi chạy script trên, bạn có một VPC production-ready với: Public Subnet (EC2 có Public IP, ra Internet qua IGW) + Private Subnet (Database, ra Internet qua NAT GW nhưng Internet không vào được) + Security Group chain (Web → DB chỉ qua SG reference).