â˜€ī¸Siang
DevOps & Cloud

AWS S3: Object Storage

GRATIS

Tutorial lengkap AWS S3 — buckets, object lifecycle, IAM policies, presigned URLs, versioning, static website hosting, replication, dan best practices keamanan

Artikel: Aws S3 Storage Artikel: Aws S3 Storage

1. Pengenalan AWS S3

Amazon Simple Storage Service (S3) adalah layanan object storage yang disediakan oleh Amazon Web Services (AWS). S3 dirancang untuk menyimpan dan mengambil data dalam jumlah besar — dari beberapa byte hingga 5 TB per object — dengan durability 99.999999999% (11 nines).

S3 menggunakan model key-value store dimana setiap object disimpan dengan key (nama file) unik di dalam sebuah bucket (container). S3 menawarkan virtually unlimited storage, high availability, dan berbagai fitur keamanan yang membuatnya menjadi standar industri untuk cloud storage.

Mengapa S3 Penting?

KeunggulanPenjelasan
Durability99.999999999% (11 nines) — data hampir tidak mungkin hilang
Availability99.99% — selalu bisa diakses kapan saja
ScalabilityTanpa batas — dari byte hingga exabytes
SecurityEnkripsi at-rest dan in-transit, fine-grained access control
PerformanceHigh throughput, low latency untuk semua storage class
Cost-EffectivePay-as-you-go, tiered pricing berdasarkan akses pattern
IntegrationTerintegrasi dengan seluruh layanan AWS (Lambda, CloudFront, dll)
Diagram: AWS S3 ARCHITECTURE

S3 API (REST)

Client (App/ Browser)

AWS SDK (boto3)

AWS CLI

Konsep dasar S3:

2. Membuat & Mengelola Bucket

Menggunakan AWS CLI

Diagram

v3 ("delete (delete marker") 2026-06-26 marker) v...

v3 (latest) content_v3.jpg 2026-06-26 v2 conten...

6. Lifecycle Management

Lifecycle rules mengotomatiskan transisi object antar storage class dan penghapusan object yang sudah tidak diperlukan. Ini sangat penting untuk mengelola biaya storage.

JSON
{
  "Rules": [
    {
      "ID": "TransitionToIA",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "logs/"
      },
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER"
        },
        {
          "Days": 365,
          "StorageClass": "DEEP_ARCHIVE"
        }
      ],
      "Expiration": {
        "Days": 730
      }
    },
    {
      "ID": "CleanupTempFiles",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "temp/"
      },
      "Expiration": {
        "Days": 7
      }
    },
    {
      "ID": "ManageOldVersions",
      "Status": "Enabled",
      "Filter": {},
      "NoncurrentVersionTransitions": [
        {
          "NoncurrentDays": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "NoncurrentDays": 90,
          "StorageClass": "GLACIER"
        }
      ],
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 365
      }
    },
    {
      "ID": "RemoveIncompleteMultipart",
      "Status": "Enabled",
      "Filter": {},
      "AbortIncompleteMultipartUpload": {
        "DaysAfterInitiation": 7
      }
    }
  ]
}
Bash
# Terapkan lifecycle rules
aws s3api put-bucket-lifecycle-configuration \
  --bucket my-app-storage-2026 \
  --lifecycle-configuration file://lifecycle.json

# Lihat lifecycle rules
aws s3api get-bucket-lifecycle-configuration \
  --bucket my-app-storage-2026

# Hapus lifecycle rules
aws s3api delete-bucket-lifecycle \
  --bucket my-app-storage-2026

7. IAM Policies & Bucket Policies

Keamanan S3 diatur melalui dua jenis policy: IAM Policy (attached ke user/role) dan Bucket Policy (attached ke bucket). Keduanya bekerja bersama untuk menentukan siapa yang bisa mengakses apa.

Bucket Policy — Contoh Umum

JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowAppReadAccess",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:role/app-role"
      },
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-app-storage-2026",
        "arn:aws:s3:::my-app-storage-2026/*"
      ]
    },
    {
      "Sid": "DenyPublicAccess",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::my-app-storage-2026",
        "arn:aws:s3:::my-app-storage-2026/*"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    },
    {
      "Sid": "AllowCloudFrontAccess",
      "Effect": "Allow",
      "Principal": {
        "Service": "cloudfront.amazonaws.com"
      },
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-app-storage-2026/public/*",
      "Condition": {
        "StringEquals": {
          "AWS:SourceArn": "arn:aws:cloudfront::123456789012:distribution/E1234567890"
        }
      }
    }
  ]
}
Bash
# Terapkan bucket policy
aws s3api put-bucket-policy \
  --bucket my-app-storage-2026 \
  --policy file://bucket-policy.json

# Lihat bucket policy
aws s3api get-bucket-policy --bucket my-app-storage-2026

# Hapus bucket policy
aws s3api delete-bucket-policy --bucket my-app-storage-2026

IAM Policy untuk User/Role

JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3Access",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-app-storage-2026",
        "arn:aws:s3:::my-app-storage-2026/uploads/*",
        "arn:aws:s3:::my-app-storage-2026/public/*"
      ]
    },
    {
      "Sid": "DenyDeleteProduction",
      "Effect": "Deny",
      "Action": "s3:DeleteObject",
      "Resource": "arn:aws:s3:::my-app-storage-2026/production/*"
    }
  ]
}
âš ī¸ Peringatan

Jangan pernah membuat bucket S3 public kecuali Anda benar-benar tahu apa yang Anda lakukan. Banyak kebocoran data terjadi karena bucket S3 yang tidak sengaja di-public-kan. Selalu gunakan BlockPublicAcls dan akses melalui CloudFront atau presigned URLs.

8. Presigned URLs

Presigned URLs memungkinkan Anda memberikan akses sementara ke object S3 tanpa perlu membuat object tersebut public. URL ini memiliki waktu kedaluwarsa dan bisa digunakan untuk upload maupun download.

Menggunakan AWS CLI

Bash
# Generate presigned URL untuk download (berlaku 1 jam)
aws s3 presign s3://my-app-storage-2026/photos/photo.jpg \
  --expires-in 3600
# https://my-app-storage-2026.s3.ap-southeast-1.amazonaws.com/photos/photo.jpg?...

# Generate presigned URL untuk download (berlaku 7 hari)
aws s3 presign s3://my-app-storage-2026/documents/report.pdf \
  --expires-in 604800

# Generate presigned URL untuk upload
aws s3 presign s3://my-app-storage-2026/uploads/new-file.jpg \
  --expires-in 3600

# Gunakan URL untuk upload via curl
curl -X PUT \
  -H "Content-Type: image/jpeg" \
  --data-binary @photo.jpg \
  "https://presigned-url-here"

Menggunakan Python (boto3)

Python
import boto3
from botocore.config import Config

s3 = boto3.client('s3',
    region_name='ap-southeast-1',
    config=Config(signature_version='s3v4')
)

BUCKET = 'my-app-storage-2026'

# Generate presigned URL untuk GET (download)
def generate_download_url(key, expires_in=3600):
    url = s3.generate_presigned_url(
        'get_object',
        Params={
            'Bucket': BUCKET,
            'Key': key,
            'ResponseContentDisposition': f'attachment; filename="{key.split("/")[-1]}"'
        },
        ExpiresIn=expires_in
    )
    return url

# Generate presigned URL untuk PUT (upload)
def generate_upload_url(key, content_type='application/octet-stream', expires_in=3600):
    url = s3.generate_presigned_url(
        'put_object',
        Params={
            'Bucket': BUCKET,
            'Key': key,
            'ContentType': content_type
        },
        ExpiresIn=expires_in
    )
    return url

# Generate presigned POST (untuk browser upload — lebih fleksibel)
def generate_presigned_post(key, content_type='image/jpeg', max_size=10*1024*1024):
    conditions = [
        ['content-length-range', 1, max_size],
        ['starts-with', '$Content-Type', content_type.split('/')[0]]
    ]

    fields = {
        'Content-Type': content_type,
        'x-amz-meta-uploaded-by': 'beebanelabs'
    }

    response = s3.generate_presigned_post(
        Bucket=BUCKET,
        Key=key,
        Fields=fields,
        Conditions=conditions,
        ExpiresIn=3600
    )
    return response
    # Returns: {'url': 'https://...', 'fields': {...}}

# Contoh penggunaan
download_url = generate_download_url('photos/photo.jpg', expires_in=7200)
upload_url = generate_upload_url('uploads/new-photo.jpg')
post_data = generate_presigned_post('uploads/user-avatar.jpg')

print(f"Download URL: {download_url}")
print(f"Upload URL: {upload_url}")
print(f"POST URL: {post_data['url']}")
print(f"POST Fields: {post_data['fields']}")

Browser Upload dengan Presigned POST

JavaScript
// Upload file langsung dari browser ke S3
async function uploadToS3(file) {
  // 1. Dapatkan presigned POST dari backend
  const response = await fetch('/api/get-upload-url', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      filename: file.name,
      contentType: file.type
    })
  });

  const { url, fields } = await response.json();

  // 2. Upload langsung ke S3
  const formData = new FormData();
  Object.entries(fields).forEach(([key, value]) => {
    formData.append(key, value);
  });
  formData.append('file', file);

  const uploadResponse = await fetch(url, {
    method: 'POST',
    body: formData
  });

  if (uploadResponse.ok) {
    console.log('Upload berhasil!');
  } else {
    console.error('Upload gagal');
  }
}

// Gunakan
document.getElementById('fileInput').addEventListener('change', (e) => {
  uploadToS3(e.target.files[0]);
});

9. Static Website Hosting

S3 bisa digunakan untuk meng-host static website (HTML, CSS, JavaScript) tanpa perlu server. Dipadukan dengan CloudFront untuk CDN global dan custom domain.

Bash
# Enable static website hosting
aws s3 website s3://my-website-bucket \
  --index-document index.html \
  --error-document error.html

# Upload website files
aws s3 sync ./public/ s3://my-website-bucket/ \
  --acl public-read

# Set content types
aws s3 cp ./public/index.html s3://my-website-bucket/ \
  --content-type "text/html" --acl public-read

aws s3 cp ./public/css/style.css s3://my-website-bucket/css/ \
  --content-type "text/css" --acl public-read

aws s3 cp ./public/js/app.js s3://my-website-bucket/js/ \
  --content-type "application/javascript" --acl public-read

# Dapatkan website URL
echo "Website URL: http://my-website-bucket.s3-website-ap-southeast-1.amazonaws.com"

Redirect Rules

XML
<!-- website-redirect-rules.xml -->
<RoutingRules>
  <RoutingRule>
    <Condition>
      <KeyPrefixEquals>old-page/</KeyPrefixEquals>
    </Condition>
    <Redirect>
      <ReplaceKeyPrefixWith>new-page/</ReplaceKeyPrefixWith>
      <HttpRedirectCode>301</HttpRedirectCode>
    </Redirect>
  </RoutingRule>
  <RoutingRule>
    <Condition>
      <HttpErrorCodeReturnedEquals>404</HttpErrorCodeReturnedEquals>
    </Condition>
    <Redirect>
      <HostName>app.example.com</HostName>
      <ReplaceKeyWith>index.html</ReplaceKeyWith>
    </Redirect>
  </RoutingRule>
</RoutingRules>

10. Encryption & Keamanan

Enkripsi di S3

EnkripsiPenjelasanKapan Digunakan
SSE-S3S3 manage encryption keys (AES-256)Kebanyakan use case standar
SSE-KMSAWS KMS manage keys (audit trail)Compliance, audit requirement
SSE-CCustomer provide encryption keysKontrol penuh atas keys
Client-SideEnkripsi sebelum upload ke S3Zero-trust, end-to-end encryption
Bash
# Set default encryption (SSE-S3)
aws s3api put-bucket-encryption \
  --bucket my-app-storage-2026 \
  --server-side-encryption-configuration '{
    "Rules": [
      {
        "ApplyServerSideEncryptionByDefault": {
          "SSEAlgorithm": "AES256"
        }
      }
    ]
  }'

# Upload dengan KMS encryption
aws s3 cp ./sensitive-data.csv s3://my-app-storage-2026/secure/ \
  --sse aws:kms \
  --sse-kms-key-id alias/my-s3-key

# Upload dengan AES-256 encryption
aws s3 cp ./data.csv s3://my-app-storage-2026/ \
  --sse AES256

# Enable Object Lock (WORM — Write Once Read Many)
# Berguna untuk compliance
aws s3api put-object-lock-configuration \
  --bucket my-app-storage-2026 \
  --object-lock-configuration '{
    "ObjectLockEnabled": true,
    "Rule": {
      "DefaultRetention": {
        "Mode": "COMPLIANCE",
        "Days": 365
      }
    }
  }'

# Enable Transfer Acceleration (upload cepat via edge locations)
aws s3api put-bucket-accelerate-configuration \
  --bucket my-app-storage-2026 \
  --accelerate-configuration Status=Enabled

# Enable server access logging
aws s3api put-bucket-logging \
  --bucket my-app-storage-2026 \
  --bucket-logging-status '{
    "LoggingEnabled": {
      "TargetBucket": "my-s3-logs",
      "TargetPrefix": "access-logs/"
    }
  }'

11. Best Practices

Keamanan

PraktikRekomendasi
Block Public AccessSelalu aktifkan Block Public Access di level bucket
Enkripsi DefaultAktifkan SSE-S3 atau SSE-KMS sebagai default encryption
Enforce HTTPSTambahkan bucket policy yang menolak request non-HTTPS
VersioningSelalu aktifkan versioning untuk bucket production
MFA DeleteAktifkan MFA Delete untuk bucket kritis
Access LoggingAktifkan server access logging untuk audit
Least PrivilegeBerikan permission seminimal mungkin sesuai kebutuhan
Object LockGunakan untuk data compliance (WORM)

Biaya & Performance

Naming Conventions

Bash
# Prefix yang baik (mudah di-manage)
photos/2026/06/26/photo.jpg
documents/reports/quarterly-report-q2-2026.pdf
users/{user_id}/avatars/avatar.jpg
backups/database/2026-06-26-dump.sql.gz
logs/app/2026/06/26/app-log-001.gz

# Hindari
PHOTO.JPG                    # Tidak ada hierarchy
a/b/c/d/e/f/file.txt         # Terlalu dalam
file with spaces.txt          # Spasi menyulitkan
â„šī¸ Catatan

S3 dirancang untuk durability 99.999999999% (11 nines) yang berarti jika Anda menyimpan 10 juta object, statistiknya hanya 1 object yang hilang per 10.000 tahun. Tapi ini bukan backup — tetap gunakan cross-region replication untuk disaster recovery.

12. Quiz Pemahaman

1. Berapa durability S3 Standard?

2. Apa itu Presigned URL?

3. Apa fungsi S3 Versioning?

4. Storage class mana yang paling murah untuk data yang sangat jarang diakses?

5. Mengapa bucket S3 sebaiknya tidak di-public-kan?

🔍 Zoom
100%
🎨 Tema