Lifecycle policy sai có thể tốn gấp 23 lần tiền storage cho cùng một object. Bài 6 dạy S3 cơ bản. Bài này giải quyết 5 bài toán production: tự động chuyển data cũ sang storage rẻ (lifecycle), replicate sang region khác (CRR), chia sẻ file tạm không public bucket (pre-signed URL), trigger Lambda khi có object mới (S3 Event), và transform object on-the-fly (Object Lambda).


  flowchart TB
    S3["S3 Bucket"]
    Lifecycle["Lifecycle Policy<br/>auto transition qua 7 storage class"]
    CRR["Cross-Region Replication<br/>DR: ap-southeast-1 → us-east-1"]
    PreSigned["Pre-signed URL<br/>temporary access 1s-7d"]
    Event["S3 Event Notification<br/>→ Lambda / SQS / SNS / EventBridge"]
    ObjLambda["Object Lambda<br/>transform on-the-fly: resize, watermark, redact"]
    S3 --> Lifecycle
    S3 --> CRR
    S3 --> PreSigned
    S3 --> Event
    S3 --> ObjLambda

Lifecycle: tiết kiệm 40-80% storage cost

S3 có 8 storage class, giá chênh đến 23x:

Storage Class~$/TB/thángRetrieval TimeUse Case
S3 Standard$23ImmediateProduction data, thường xuyên truy cập
Intelligent-Tiering$23 + monitoring (xem ghi chú)ImmediateAccess pattern không dự đoán được
Standard-IA$12.50ImmediateTruy cập <1 lần/tháng
One Zone-IA$10ImmediateData reproducible, không cần HA
S3 Express One Zone~$8MillisecondWorkload cần latency cực thấp
Glacier Instant Retrieval$4MillisecondsArchive cần truy cập nhanh
Glacier Flexible Retrieval$3.601-5 phútBackup lâu dài
Glacier Deep Archive$112-48 giờCompliance archive

Ghi chú Intelligent-Tiering: Không phải một mức giá cố định. Intelligent-Tiering tự động chuyển object giữa các tiers: Frequent Access (giá như Standard), Infrequent Access (giá như Standard-IA), Archive Instant Access (giá như Glacier Instant Retrieval), và Deep Archive Access (giá như Glacier Deep Archive). Phí monitoring $0.0025/1K objects/tháng là phụ thêm. Xem chi tiết ở phần bên dưới.

Intelligent-Tiering: auto optimize

aws s3api put-bucket-intelligent-tiering-configuration --bucket myapp-data --id default --intelligent-tiering-configuration '{
  "Status": "Enabled",
  "Tierings": [
    {"Days": 0, "AccessTier": "ARCHIVE_ACCESS"},
    {"Days": 90, "AccessTier": "DEEP_ARCHIVE_ACCESS"}
  ]
}'

Tự động chuyển object giữa Frequent / Infrequent / Archive Instant Access tiers dựa trên access pattern thực tế. Phí monitoring: $0.0025/1K objects/tháng.

Lifecycle policy cho data predictable

aws s3api put-bucket-lifecycle-configuration --bucket myapp-logs --lifecycle-configuration '{
  "Rules": [{
    "Id": "logs-to-glacier", "Status": "Enabled",
    "Filter": {"Prefix": "logs/"},
    "Transitions": [
      {"Days": 30, "StorageClass": "STANDARD_IA"},
      {"Days": 90, "StorageClass": "GLACIER_FLEXIBLE_RETRIEVAL"}
    ],
    "Expiration": {"Days": 365}
  }]
}'

Cross-Region Replication

aws s3api put-bucket-replication --bucket myapp-prod --replication-configuration '{
  "Role": "arn:aws:iam::123456789012:role/s3-crr-role",
  "Rules": [{
    "Id": "crr-to-dr", "Status": "Enabled", "Priority": 1,
    "DeleteMarkerReplication": {"Status": "Enabled"},
    "Destination": {"Bucket": "arn:aws:s3:::myapp-dr-us-east-1", "StorageClass": "STANDARD"}
  }]
}'

S3 Batch Replication để sync object hiện có (CRR chỉ replicate object mới).


Pre-signed URL: bảo mật đúng cách

import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { getSignedUrl } from "@aws-sdk/s3-request-presigner";

const url = await getSignedUrl(
  s3,
  new GetObjectCommand({
    Bucket: "myapp-data",
    Key: "reports/sales-2026.pdf",
  }),
  { expiresIn: 3600 }
); // Ngắn nhất có thể
Pre-signed URL = ai có URL đó là có quyền. GET URL = download, PUT URL = upload. Set expiresIn ngắn nhất có thể. Với upload, thêm Content-Length validation ở backend. Incident $47K Lambda recursive loop: S3 event trigger không filter prefix/suffix → Lambda tự gọi chính nó qua log file.

S3 Event → Lambda/SQS/SNS/EventBridge

aws s3api put-bucket-notification-configuration --bucket myapp-uploads --notification-configuration '{
  "LambdaFunctionConfigurations": [{
    "Id": "image-resize", "LambdaFunctionArn": "...",
    "Events": ["s3:ObjectCreated:*"],
    "Filter": {"Key": {"FilterRules": [
      {"Name": "prefix", "Value": "uploads/"}, {"Name": "suffix", "Value": ".jpg"}
    ]}}
  }]
}'

Luôn dùng prefix/suffix filter — không bao giờ dùng * cho mọi event. Đây là bài học từ incident $47K Lambda recursive loop.


S3 không chỉ là bucket chứa file, biết lifecycle và event routing là lúc nó thành backbone cho event-driven architecture.

  • Intelligent-Tiering cho access pattern không dự đoán được, lifecycle policy cho data predictable
  • CRR cho DR, SRR (Same-Region Replication) cho compliance
  • Pre-signed URL: expiresIn ngắn nhất, Content-Length validation, authentication layer bên ngoài
  • S3 Event: luôn filter prefix/suffix, không * — tránh Lambda recursive loop
  • Object Lambda: transform on-the-fly (watermark, resize, redact PII)

Bài sau: Phần 8: EC2 thực hành — từ AMI đến production instance