Triển Khai Laravel Lên AWS Qua Console (Phần 4): ALB, CloudFront CDN & SSL Với ACM
Ở Phần 3, chúng ta đã kết nối Laravel với RDS, S3, và Redis. Giờ hãy đặt cửa trước production: ALB cho cân bằng tải và SSL, CloudFront cho CDN, và Route 53 cho DNS.
Mọi thao tác trong bài này thực hiện trên giao diện Console.
Chứng Chỉ SSL Với ACM
AWS Certificate Manager cung cấp chứng chỉ SSL miễn phí — nhưng chỉ dùng được với dịch vụ AWS (ALB, CloudFront), không trực tiếp trên EC2.
Quan trọng: Chúng ta cần hai chứng chỉ:
- Một cho ALB — tạo ở region hiện tại (ap-northeast-1)
- Một cho CloudFront — bắt buộc tạo ở us-east-1 (N. Virginia)
Bước 1a: Chứng Chỉ Cho ALB (Region ap-northeast-1)
- Kiểm tra region: ap-northeast-1 (Tokyo)
- Thanh tìm kiếm → "Certificate Manager" → click AWS Certificate Manager
- Click "Request"
| Thiết lập | Giá trị |
|---|---|
| Certificate type | Request a public certificate |
Click Next.
| Thiết lập | Giá trị |
|---|---|
| Fully qualified domain name | your-domain.com |
| Add another name | *.your-domain.com (wildcard cho subdomains) |
| Validation method | DNS validation (recommended) |
| Key algorithm | RSA 2048 |
- Click "Request"
Bước 1b: Chứng Chỉ Cho CloudFront (Region us-east-1)
- Chuyển region sang us-east-1 (N. Virginia) — click region ở góc phải trên
- Lặp lại hoàn toàn bước 1a: Request certificate với cùng domain names
- Nhớ chuyển lại region về ap-northeast-1 sau khi xong
Bước 1c: Xác Thực DNS
Sau khi request, ACM hiện status Pending validation:
- Click vào certificate vừa tạo
- Phần Domains → thấy CNAME name và CNAME value
- Hai cách thêm DNS record:
Cách 1 — Nếu domain ở Route 53 (nhanh nhất):
- Click "Create records in Route 53" → AWS tự thêm CNAME records
- Xong, đợi vài phút
Cách 2 — Nếu domain ở provider khác:
- Copy CNAME name và CNAME value
- Vào DNS provider (Cloudflare, GoDaddy, v.v.) → thêm CNAME record
- Đợi 5-30 phút cho validation
- Status chuyển sang Issued ✅
Làm tương tự cho cả hai certificates (ap-northeast-1 và us-east-1).
Application Load Balancer (ALB)
Bước 2a: Tạo Target Group
Target group định nghĩa EC2 instances sẽ nhận traffic.
- Đảm bảo region là ap-northeast-1
- EC2 → Target Groups (menu bên trái, phần Load Balancing)
- Click "Create target group"
Specify Group Details
| Thiết lập | Giá trị |
|---|---|
| Target type | Instances |
| Target group name | laravel-tg |
| Protocol | HTTP |
| Port | 80 |
| VPC | laravel-production-vpc |
| Protocol version | HTTP1 |
Health Checks
| Thiết lập | Giá trị |
|---|---|
| Health check protocol | HTTP |
| Health check path | /up |
Expand Advanced health check settings:
| Thiết lập | Giá trị |
|---|---|
| Port | Traffic port |
| Healthy threshold | 2 |
| Unhealthy threshold | 3 |
| Timeout | 5 seconds |
| Interval | 30 seconds |
| Success codes | 200 |
/uplà route health check mặc định của Laravel (từ v11). Trả về 200 nếu app hoạt động.
- Click Next
Register Targets
- Trong danh sách instances, tick
laravel-web-01 - Port:
80 - Click "Include as pending below"
- Click "Create target group"
Bước 2b: Tạo ALB
- EC2 → Load Balancers → Create load balancer
- Chọn "Application Load Balancer" → Create
Basic Configuration
| Thiết lập | Giá trị |
|---|---|
| Load balancer name | laravel-alb |
| Scheme | Internet-facing |
| IP address type | IPv4 |
Network Mapping
| Thiết lập | Giá trị |
|---|---|
| VPC | laravel-production-vpc |
| Mappings | ✅ ap-northeast-1a → public subnet 1 |
✅ ap-northeast-1c → public subnet 2 |
ALB phải nằm ở public subnets vì nó nhận traffic từ internet.
Security Groups
Chọn laravel-alb-sg (bỏ tick default security group)
Listeners and Routing
Listener 1 (đã có sẵn):
| Thiết lập | Giá trị |
|---|---|
| Protocol | HTTP |
| Port | 80 |
| Default action | Redirect to → HTTPS, Port 443, Status code 301 |
Listener 2 — thêm mới (click "Add listener"):
| Thiết lập | Giá trị |
|---|---|
| Protocol | HTTPS |
| Port | 443 |
| Default action | Forward to → laravel-tg |
| Default SSL/TLS certificate | Chọn certificate your-domain.com (region ap-northeast-1) |
| Security policy | ELBSecurityPolicy-TLS13-1-2-2021-06 |
- Click "Create load balancer"
- Đợi state chuyển sang Active
Bước 2c: Lấy ALB DNS Name
- EC2 → Load Balancers → click
laravel-alb - Tab Description → ghi lại DNS name (dạng
laravel-alb-xxxx.ap-northeast-1.elb.amazonaws.com)
Cách ALB + EC2 Hoạt Động
Client → HTTPS :443 → ALB (SSL termination) → HTTP :80 → EC2 (Nginx)
ALB xử lý SSL. Traffic giữa ALB và EC2 là HTTP thuần trong VPC (mạng riêng, an toàn).
Bước 2d: Laravel Trust ALB Proxy
Vì ALB terminate SSL và forward HTTP, Laravel cần biết protocol gốc là HTTPS. SSH vào EC2 và cập nhật:
// bootstrap/app.php (Laravel 11+)
->withMiddleware(function (Middleware $middleware) {
$middleware->trustProxies(
at: '*',
headers: Request::HEADER_X_FORWARDED_FOR |
Request::HEADER_X_FORWARDED_HOST |
Request::HEADER_X_FORWARDED_PORT |
Request::HEADER_X_FORWARDED_PROTO |
Request::HEADER_X_FORWARDED_AWS_ELB,
);
})
Không có config này, url(), asset(), và redirect() sẽ tạo URL http:// thay vì https://.
Route 53 — DNS
Bước 3a: Tạo Hosted Zone
- Thanh tìm kiếm → "Route 53" → click Route 53
- Menu bên trái → Hosted zones
- Click "Create hosted zone"
| Thiết lập | Giá trị |
|---|---|
| Domain name | your-domain.com |
| Type | Public hosted zone |
- Click "Create hosted zone"
Bước 3b: Cập Nhật Nameservers
- Click vào hosted zone vừa tạo
- Tìm record NS (Name Server) — có 4 nameservers dạng:
ns-xxxx.awsdns-xx.org ns-xxxx.awsdns-xx.co.uk ns-xxxx.awsdns-xx.com ns-xxxx.awsdns-xx.net - Vào domain registrar của bạn (GoDaddy, Namecheap, v.v.)
- Thay nameservers hiện tại bằng 4 nameservers từ Route 53
- Đợi 24-48 giờ cho DNS propagation (thường nhanh hơn nhiều)
Bước 3c: Trỏ Domain Về ALB
- Ở hosted zone → click "Create record"
- Dùng Wizard (mặc định):
| Thiết lập | Giá trị |
|---|---|
| Record name | để trống (cho root domain) |
| Record type | A |
| Alias | ✅ Toggle bật |
| Route traffic to | Alias to Application and Classic Load Balancer |
| Region | ap-northeast-1 |
| Load balancer | Chọn laravel-alb |
-
Click "Create records"
-
Tạo thêm record cho www:
| Thiết lập | Giá trị |
|---|---|
| Record name | www |
| Record type | A |
| Alias | ✅ |
| Route traffic to | Alias to Application and Classic Load Balancer → laravel-alb |
- Create records
Bước 3d: Kiểm Tra
Sau khi DNS propagate:
https://your-domain.com→ ALB → EC2 → Laravel ✅http://your-domain.com→ redirect sang HTTPS ✅
CloudFront CDN
CloudFront cache assets tĩnh (CSS, JS, ảnh) ở edge locations toàn cầu, giảm latency cho người dùng xa region AWS.
Bước 4a: Tạo Distribution
- Thanh tìm kiếm → "CloudFront" → click CloudFront
- Click "Create distribution"
Origin Settings
| Thiết lập | Giá trị |
|---|---|
| Origin domain | laravel-alb-xxxx.ap-northeast-1.elb.amazonaws.com (chọn ALB) |
| Protocol | HTTPS only |
| HTTP Port | 80 |
| HTTPS Port | 443 |
Origin là ALB, không phải EC2 trực tiếp.
Default Cache Behavior
| Thiết lập | Giá trị |
|---|---|
| Path pattern | Default (*) |
| Compress objects automatically | Yes |
| Viewer protocol policy | Redirect HTTP to HTTPS |
| Allowed HTTP methods | GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE |
| Cache key and origin requests | Cache policy and origin request policy |
| Cache policy | CachingDisabled |
| Origin request policy | AllViewerExceptHostHeader |
Default behavior = không cache vì nội dung PHP là động (HTML thay đổi theo user/request).
Thêm Cache Behavior Cho Assets
Sau khi tạo distribution, thêm behavior cho assets tĩnh:
- Tab Behaviors → Create behavior
Behavior cho /build/* (Vite assets):
| Thiết lập | Giá trị |
|---|---|
| Path pattern | /build/* |
| Origin | ALB origin |
| Viewer protocol policy | Redirect HTTP to HTTPS |
| Allowed HTTP methods | GET, HEAD |
| Cache policy | CachingOptimized |
Behavior cho /images/*:
| Thiết lập | Giá trị |
|---|---|
| Path pattern | /images/* |
| Viewer protocol policy | Redirect HTTP to HTTPS |
| Allowed HTTP methods | GET, HEAD |
| Cache policy | CachingOptimized |
Chiến Lược Cache Giải Thích
| Path | Cache | Tại sao |
|---|---|---|
/build/* |
Cache dài (CachingOptimized) | Vite hash filenames — file mới = URL mới |
/images/* |
Cache dài | Ảnh tĩnh ít thay đổi |
* (mặc định) |
Không cache | Response PHP động |
Settings
| Thiết lập | Giá trị |
|---|---|
| Price class | Use all edge locations (hoặc một trong các option rẻ hơn) |
| Alternate domain name (CNAME) | your-domain.com và www.your-domain.com |
| Custom SSL certificate | Chọn certificate từ us-east-1 |
| Default root object | để trống |
| Standard logging | Off (bật nếu cần debug) |
- Click "Create distribution"
- Đợi 5-15 phút cho status Deployed
Bước 4b: Cập Nhật Route 53 Trỏ Về CloudFront
Giờ domain cần trỏ đến CloudFront thay vì ALB:
- Route 53 → Hosted zones → your-domain.com
- Click vào record A (root domain) → Edit record
- Thay đổi:
| Thiết lập | Giá trị mới |
|---|---|
| Route traffic to | Alias to CloudFront distribution |
| Distribution | Chọn distribution vừa tạo |
- Save
- Lặp lại cho record www
Luồng Traffic Hoàn Chỉnh
User → CloudFront Edge → Cache HIT → Response (nhanh!)
→ Cache MISS → ALB → EC2 → Response
CloudFront còn cung cấp bảo vệ DDoS miễn phí (AWS Shield Standard).
Kiến Trúc Cập Nhật
Route 53
│
▼
CloudFront (CDN)
├── /build/* → Cached
├── /images/* → Cached
└── /* → Pass-through
│
▼
ALB (HTTPS → HTTP)
├── SSL termination (ACM cert)
└── Health check: /up
│
▼
EC2 (Nginx + PHP-FPM)
├── → RDS MySQL
├── → ElastiCache Redis
└── → S3
Checklist Sau Phần 4
- ACM certificate ở ap-northeast-1: Issued
- ACM certificate ở us-east-1: Issued
- Target group
laravel-tgvới EC2 Healthy - ALB
laravel-albstate Active - HTTP → HTTPS redirect hoạt động
- Route 53 hosted zone đã tạo
- Nameservers đã cập nhật ở domain registrar
- CloudFront distribution Deployed
- Domain trỏ về CloudFront
-
https://your-domain.comhoạt động ✅ - Laravel TrustProxies đã cấu hình
Hạ tầng hoàn chỉnh! Tiếp theo: tự động hóa deploy.
Điều hướng Series:
- ← Phần 0: Chuẩn Bị
- ← Phần 1: Kiến Trúc & VPC
- ← Phần 2: EC2 & Amazon Linux 2023
- ← Phần 3: RDS, S3 & ElastiCache
- Phần 4: ALB, CloudFront & SSL (Bạn đang ở đây)
- Phần 5: CI/CD & Zero-Downtime Deploy →