Cập Nhật Nội Dung CloudFront: Tạo Invalidation Để Xóa Cache Edge Ngay Lập Tức
Bạn vừa upload file mới lên S3, reload trang và vẫn thấy phiên bản cũ — đây là tình huống kinh điển khi làm việc với CloudFront. Cache tại edge location chưa hết TTL, nên CloudFront tiếp tục phục vụ object cũ từ bộ nhớ đệm mà không hề biết S3 đã thay đổi. Giải pháp trực tiếp nhất là tạo một CloudFront Invalidation để buộc các edge node xóa bản cache và fetch lại từ origin.
TL;DR — Cập Nhật Nội Dung CloudFront Nhanh
| Bước | Hành động | Kết quả |
|---|---|---|
| 1 | Upload file mới lên S3 | Origin đã có nội dung mới |
| 2 | Tạo Invalidation trên distribution | Edge cache bị xóa |
| 3 | Chờ invalidation hoàn tất (~1-5 phút) | Request tiếp theo fetch từ S3 |
| 4 | Xác minh bằng curl hoặc browser | Nội dung mới được phục vụ |
CloudFront Cache Hoạt Động Như Thế Nào
CloudFront duy trì một mạng lưới edge location toàn cầu. Khi người dùng request một object, CloudFront kiểm tra cache tại edge gần nhất. Nếu object đã được cache và chưa hết TTL, CloudFront trả về bản cache mà không liên hệ S3. Đây là lý do tại sao việc thay file trên S3 không tự động cập nhật những gì người dùng nhìn thấy.
TTL được kiểm soát bởi header Cache-Control trên object S3, hoặc bởi cài đặt cache behavior trong CloudFront distribution. Nếu bạn set TTL là 86400 giây (1 ngày), edge location sẽ giữ bản cũ tối đa 24 giờ trừ khi bị invalidate.
- User Request: Trình duyệt gửi request đến CloudFront edge location gần nhất.
- Cache Hit: Nếu object còn trong cache và TTL chưa hết, edge trả về ngay — S3 không được hỏi.
- Cache Miss / Invalidated: Edge fetch từ S3 origin, cache lại, rồi trả về cho user.
- Invalidation: Khi bạn tạo invalidation, CloudFront đánh dấu object là expired tại tất cả edge location, buộc request tiếp theo phải fetch từ origin.
Tạo CloudFront Invalidation — Từng Bước Cụ Thể
Có hai cách chính: AWS Management Console và AWS CLI. CLI phù hợp hơn cho automation và CI/CD pipeline.
Cách 1: Dùng AWS CLI (Khuyến nghị cho Automation)
Trước tiên, xác định Distribution ID của bạn. Nếu chưa biết, lấy danh sách distributions:
aws cloudfront list-distributions \
--query 'DistributionList.Items[*].{ID:Id,Domain:DomainName,Status:Status}' \
--output table
Sau khi có Distribution ID, tạo invalidation cho một file cụ thể:
aws cloudfront create-invalidation \
--distribution-id E1EXAMPLE12345 \
--paths '/images/banner.jpg'
Để invalidate nhiều path cùng lúc:
aws cloudfront create-invalidation \
--distribution-id E1EXAMPLE12345 \
--paths '/images/banner.jpg' '/css/style.css' '/js/app.js'
Để invalidate toàn bộ cache (dùng cẩn thận — xem phần lưu ý về chi phí bên dưới):
aws cloudfront create-invalidation \
--distribution-id E1EXAMPLE12345 \
--paths '/*'
Output của lệnh trên sẽ trả về một Invalidation object với Id và Status: InProgress. Lưu lại Invalidation ID để theo dõi trạng thái.
Theo Dõi Trạng Thái Invalidation
Invalidation không hoàn tất ngay lập tức. Dùng lệnh sau để kiểm tra khi nào nó chuyển sang Completed:
aws cloudfront get-invalidation \
--distribution-id E1EXAMPLE12345 \
--id IEXAMPLE123456
Nếu muốn chờ cho đến khi invalidation hoàn tất trong script:
aws cloudfront wait invalidation-completed \
--distribution-id E1EXAMPLE12345 \
--id IEXAMPLE123456
Cách 2: Dùng AWS Management Console
- Mở CloudFront console → chọn distribution của bạn.
- Chọn tab Invalidations → nhấn Create invalidation.
- Nhập object path (ví dụ:
/images/banner.jpghoặc/*). - Nhấn Create invalidation và chờ status chuyển sang Completed.
IAM Permission Cần Thiết
Nếu bạn đang chạy lệnh CLI từ một IAM role hoặc user, cần đảm bảo có permission sau. Thiếu permission này sẽ gặp lỗi AccessDenied mà không có thông báo rõ ràng về nguyên nhân.
🔽 Xem IAM Policy mẫu cho CloudFront Invalidation
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowCloudFrontInvalidation",
"Effect": "Allow",
"Action": [
"cloudfront:CreateInvalidation",
"cloudfront:GetInvalidation",
"cloudfront:ListInvalidations"
],
"Resource": "arn:aws:cloudfront::123456789012:distribution/E1EXAMPLE12345"
},
{
"Sid": "AllowListDistributions",
"Effect": "Allow",
"Action": "cloudfront:ListDistributions",
"Resource": "*"
}
]
}
Lưu ý: cloudfront:ListDistributions yêu cầu "Resource": "*" vì đây là list action không hỗ trợ resource-level restriction. Các action còn lại có thể scope xuống ARN của distribution cụ thể.
Cập Nhật Nội Dung CloudFront — Chiến Lược Dài Hạn Tốt Hơn
Invalidation giải quyết vấn đề ngay lập tức, nhưng nếu bạn deploy thường xuyên, có một cách tiếp cận tốt hơn về mặt kiến trúc: cache busting bằng versioned filename.
- Invalidation (reactive): File giữ nguyên tên, bạn phải tạo invalidation sau mỗi lần thay đổi. Phát sinh chi phí nếu vượt quota miễn phí.
- Versioned Filename (proactive): Mỗi lần deploy, file có tên mới (ví dụ:
app.v2.jsthay vìapp.js). CloudFront tự động fetch file mới vì cache key khác. Không cần invalidation. - Kết hợp: Dùng versioned filename cho static assets (JS, CSS, images), dùng invalidation cho HTML và các file không thể đổi tên.
Nghĩ về invalidation như việc gọi điện cho từng bưu cục để thu hồi thư đã gửi. Versioned filename giống như gửi thư mới với địa chỉ khác — không cần thu hồi gì cả.
Lưu Ý Về Chi Phí Invalidation
AWS cung cấp 1.000 invalidation path miễn phí mỗi tháng cho mỗi distribution. Sau đó, mỗi path tính phí riêng. Wildcard path như /* được tính là một path duy nhất, không phải theo số lượng file thực tế bị invalidate.
Pricing và quota cụ thể thay đổi theo thời gian — luôn kiểm tra trang pricing chính thức của AWS CloudFront.
Kinh Nghiệm Thực Tế: Khi Invalidation Chạy Xong Nhưng Vẫn Thấy Nội Dung Cũ
Đây là tình huống hay gặp nhất và thường bị chẩn đoán sai. Invalidation đã Completed, nhưng reload trang vẫn thấy file cũ. Phản xạ đầu tiên thường là 'CloudFront chưa propagate xong' và tiếp tục chờ. Sai.
Nguyên nhân thực tế thường là browser cache hoặc cache của ISP/proxy trung gian, không phải CloudFront. CloudFront đã xóa cache rồi, nhưng trình duyệt vẫn đang dùng bản local của nó.
Cách xác minh nhanh: dùng curl với header để bypass browser cache và kiểm tra response header từ CloudFront:
curl -I -H 'Cache-Control: no-cache' \
'https://d1example.cloudfront.net/images/banner.jpg'
Kiểm tra header X-Cache trong response:
X-Cache: Miss from cloudfront— CloudFront đã fetch từ origin (invalidation hoạt động đúng).X-Cache: Hit from cloudfront— CloudFront vẫn đang serve từ cache (invalidation chưa propagate đến edge này, hoặc path không khớp).
Nếu curl trả về nội dung mới nhưng browser vẫn hiển thị cũ, vấn đề nằm ở browser cache — không phải CloudFront. Hard refresh (Ctrl+Shift+R hoặc Cmd+Shift+R) hoặc mở incognito window để xác nhận.
Một điểm tinh tế hơn: path trong invalidation phải khớp chính xác với cache key. Nếu distribution của bạn có cấu hình forward query string, thì /images/banner.jpg và /images/banner.jpg?v=1 là hai cache entry khác nhau. Invalidate /images/banner.jpg sẽ không xóa entry có query string.
Tích Hợp Invalidation Vào CI/CD Pipeline
Trong môi trường production, invalidation nên chạy tự động sau mỗi lần deploy. Ví dụ đơn giản cho script deploy:
🔽 Xem script deploy mẫu với S3 sync và CloudFront invalidation
#!/bin/bash
set -e
DISTRIBUTION_ID="E1EXAMPLE12345"
S3_BUCKET="s3://my-website-bucket"
BUILD_DIR="./dist"
# Sync build artifacts lên S3
aws s3 sync "$BUILD_DIR" "$S3_BUCKET" \
--delete \
--cache-control 'max-age=31536000' \
--exclude 'index.html'
# HTML không cache lâu
aws s3 cp "$BUILD_DIR/index.html" "$S3_BUCKET/index.html" \
--cache-control 'no-cache, no-store, must-revalidate'
# Invalidate HTML files (assets dùng versioned filename nên không cần)
INVALIDATION_ID=$(aws cloudfront create-invalidation \
--distribution-id "$DISTRIBUTION_ID" \
--paths '/index.html' \
--query 'Invalidation.Id' \
--output text)
echo "Invalidation created: $INVALIDATION_ID"
# Chờ invalidation hoàn tất
aws cloudfront wait invalidation-completed \
--distribution-id "$DISTRIBUTION_ID" \
--id "$INVALIDATION_ID"
echo "Deploy hoàn tất. Nội dung mới đã được phục vụ."
Wrap-Up: Cập Nhật Nội Dung CloudFront Hiệu Quả
Khi cần xóa cache CloudFront ngay lập tức, aws cloudfront create-invalidation là công cụ trực tiếp nhất. Nhưng nếu bạn deploy thường xuyên, kết hợp versioned filename cho static assets với invalidation chỉ cho HTML sẽ giảm chi phí và phức tạp vận hành đáng kể. Luôn xác minh bằng curl -I và kiểm tra header X-Cache trước khi kết luận invalidation không hoạt động — browser cache là thủ phạm phổ biến hơn bạn nghĩ.
Tham khảo thêm: AWS CloudFront Developer Guide — Invalidating Files.
Glossary — Thuật Ngữ Chính
| Thuật ngữ | Giải thích |
|---|---|
| Edge Location | Điểm hiện diện (PoP) của CloudFront trên toàn cầu, nơi cache được lưu trữ gần người dùng. |
| Invalidation | Yêu cầu gửi đến CloudFront để đánh dấu một hoặc nhiều object là hết hạn tại tất cả edge location. |
| TTL (Time To Live) | Thời gian tối đa một object được giữ trong cache trước khi CloudFront fetch lại từ origin. |
| Cache Key | Định danh duy nhất cho một cached object, thường là URL path và có thể bao gồm query string hoặc header tùy cấu hình. |
| Cache Busting | Kỹ thuật thêm version vào tên file hoặc URL để buộc browser và CDN fetch phiên bản mới mà không cần invalidation. |
Nhận xét
Đăng nhận xét