S3 & Storage Solutions: Từ cơ bản đến nâng cao

Làm chủ S3 buckets, policies, versioning và các storage classes. So sánh EBS, EFS và Glacier.

Amazon S3 là gì?

S3 (Simple Storage Service) là dịch vụ object storage với độ bền dữ liệu 99.999999999% (11 nines). Phù hợp cho static files, backups, data lakes.

Các khái niệm cơ bản

ConceptMô tả
BucketContainer chứa objects (tên globally unique)
ObjectFile + metadata (max 5TB)
KeyĐường dẫn đến object
Storage ClassLoại lưu trữ (Standard, IA, Glacier…)

Triển khai S3 với Terraform

S3 Bucket với Best Practices

# main.tf

# S3 Bucket
resource "aws_s3_bucket" "main" {
  bucket = "${var.project_name}-${var.environment}-assets"

  tags = {
    Name        = "${var.project_name}-assets"
    Environment = var.environment
  }
}

# Enable versioning
resource "aws_s3_bucket_versioning" "main" {
  bucket = aws_s3_bucket.main.id
  
  versioning_configuration {
    status = "Enabled"
  }
}

# Server-side encryption (AES-256)
resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
  bucket = aws_s3_bucket.main.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
    bucket_key_enabled = true
  }
}

# Block public access (bật mặc định!)
resource "aws_s3_bucket_public_access_block" "main" {
  bucket = aws_s3_bucket.main.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# Lifecycle rules - chuyển sang storage class rẻ hơn
resource "aws_s3_bucket_lifecycle_configuration" "main" {
  bucket = aws_s3_bucket.main.id

  rule {
    id     = "transition-to-ia"
    status = "Enabled"

    transition {
      days          = 30
      storage_class = "STANDARD_IA"
    }

    transition {
      days          = 90
      storage_class = "GLACIER"
    }

    expiration {
      days = 365
    }

    noncurrent_version_transition {
      noncurrent_days = 30
      storage_class   = "GLACIER"
    }

    noncurrent_version_expiration {
      noncurrent_days = 90
    }
  }
}

Bucket Policy - Allow CloudFront Access

# S3 bucket policy cho CloudFront OAC
resource "aws_s3_bucket_policy" "cloudfront" {
  bucket = aws_s3_bucket.main.id

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid       = "AllowCloudFrontOAC"
        Effect    = "Allow"
        Principal = {
          Service = "cloudfront.amazonaws.com"
        }
        Action   = "s3:GetObject"
        Resource = "${aws_s3_bucket.main.arn}/*"
        Condition = {
          StringEquals = {
            "AWS:SourceArn" = aws_cloudfront_distribution.main.arn
          }
        }
      }
    ]
  })
}

Static Website Hosting

# Enable static website hosting
resource "aws_s3_bucket_website_configuration" "website" {
  bucket = aws_s3_bucket.website.id

  index_document {
    suffix = "index.html"
  }

  error_document {
    key = "error.html"
  }
}

# Upload files
resource "aws_s3_object" "index" {
  bucket       = aws_s3_bucket.website.id
  key          = "index.html"
  source       = "${path.module}/website/index.html"
  content_type = "text/html"
  etag         = filemd5("${path.module}/website/index.html")
}

AWS CLI Commands

# Tạo bucket
aws s3 mb s3://my-unique-bucket-name --region ap-southeast-1

# Upload file
aws s3 cp file.txt s3://my-bucket/

# Upload folder (recursive)
aws s3 cp ./folder s3://my-bucket/folder --recursive

# Sync folder (chỉ upload files thay đổi)
aws s3 sync ./build s3://my-bucket/ --delete

# List objects
aws s3 ls s3://my-bucket/

# Download file
aws s3 cp s3://my-bucket/file.txt ./

# Generate presigned URL (valid 1 hour)
aws s3 presign s3://my-bucket/private-file.pdf --expires-in 3600

# Enable versioning
aws s3api put-bucket-versioning \
  --bucket my-bucket \
  --versioning-configuration Status=Enabled

Storage Classes và Chi phí

ClassAvailabilityUse CaseGiá*
Standard99.99%Frequently accessed$0.023/GB
Standard-IA99.9%30+ days, infrequent$0.0125/GB
Glacier Instant99.9%Archive, immediate access$0.004/GB
Glacier Flexible99.99%Archive, 3-5h retrieval$0.0036/GB
Glacier Deep Archive99.99%Long-term, 12h retrieval$0.00099/GB

*Giá tham khảo US East, có thể thay đổi.


So sánh Storage Services

ServiceTypeUse Case
S3ObjectFiles, backups, static sites
EBSBlockEC2 disks, databases
EFSFile (NFS)Shared file system
FSxFileWindows/Lustre file system

S3 Security Best Practices

# 1. Luôn block public access
resource "aws_s3_bucket_public_access_block" "example" {
  bucket                  = aws_s3_bucket.example.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# 2. Enable encryption
resource "aws_s3_bucket_server_side_encryption_configuration" "example" {
  bucket = aws_s3_bucket.example.id
  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

# 3. Enable versioning (protect against accidental deletes)
resource "aws_s3_bucket_versioning" "example" {
  bucket = aws_s3_bucket.example.id
  versioning_configuration {
    status = "Enabled"
  }
}

# 4. Enable access logging
resource "aws_s3_bucket_logging" "example" {
  bucket        = aws_s3_bucket.example.id
  target_bucket = aws_s3_bucket.logs.id
  target_prefix = "s3-access-logs/"
}

Outputs

output "bucket_name" {
  value = aws_s3_bucket.main.id
}

output "bucket_arn" {
  value = aws_s3_bucket.main.arn
}

output "bucket_regional_domain_name" {
  value = aws_s3_bucket.main.bucket_regional_domain_name
}

Bài tiếp theo: VPC & Networking - Xây dựng hạ tầng mạng với Terraform.