Cloud Computing

Panduan Lengkap Amazon S3 : Fitur dan Cara Pakai

M
MUGHU
41 menit baca
Panduan Lengkap Amazon S3 : Fitur dan Cara Pakai
Daftar isi

Amazon S3 adalah layanan penyimpanan objek dari Amazon Web Services yang cocok untuk menyimpan gambar, video, dokumen, cadangan data, berkas aplikasi, hingga dataset analitik. Kapasitasnya bertambah otomatis, data bisa diakses lewat internet atau jaringan AWS, dan biayanya mengikuti pemakaian tanpa biaya minimum.

Amazon S3 adalah object storage yang menyimpan data sebagai objek di dalam bucket. Setiap objek terdiri dari isi berkas, metadata, dan key unik yang dipakai untuk menemukannya.

Panduan ini menunjukkan cara memakai AWS S3 dari awal sampai siap dipakai oleh aplikasi. Teman-Teman akan membuat bucket, mengunggah berkas lewat AWS CLI dan Python, mengatur hak akses, membuat presigned URL, mengaktifkan versioning, menerapkan lifecycle policy, serta memahami biaya dan pilihan storage class.

Contohnya dibuat cukup dekat dengan kebutuhan di Indonesia, seperti menyimpan foto produk toko daring di Jakarta, dokumen cabang di Surabaya, hasil ekspor laporan di Bandung, atau cadangan aplikasi yang berjalan di AWS Region Asia Pacific Jakarta.

Masalah penyimpanan yang diselesaikan Amazon S3

Banyak aplikasi mulai dari penyimpanan lokal yang sederhana. Foto produk ditaruh di folder server, dokumen pengguna disimpan pada disk mesin virtual, dan cadangan database dipindahkan secara manual.

Cara itu masih masuk akal saat data sedikit. Masalah mulai terasa ketika volume data naik:

  • Kapasitas disk cepat habis.
  • Menambah disk membutuhkan pekerjaan operasional.
  • Berkas ikut hilang jika server rusak dan cadangannya tidak benar.
  • Banyak server perlu mengakses kumpulan berkas yang sama.
  • Distribusi konten ke pengguna di berbagai kota menjadi lambat.
  • Pengaturan retensi dan penghapusan data sulit dilakukan secara konsisten.
  • Biaya infrastruktur tetap berjalan meski kapasitas tidak terpakai penuh.

Amazon S3 memisahkan penyimpanan berkas dari server aplikasi. Aplikasi cukup mengirim objek ke sebuah bucket, lalu mengambilnya kembali memakai API saat dibutuhkan.

Pendekatan ini penting karena server aplikasi bisa diganti, ditambah, atau dipindahkan tanpa harus memindahkan seluruh koleksi berkas bersamanya.

Cara kerja Amazon S3 dalam bahasa sederhana

Bayangkan sebuah gudang digital.

  • Bucket adalah gudangnya.
  • Object adalah barang yang disimpan.
  • Key adalah kode lokasi unik untuk menemukan barang.
  • Metadata adalah label yang menjelaskan isi barang.
  • Region adalah wilayah tempat gudang berada.
  • Storage class menentukan biaya dan kecepatan akses barang.

Misalnya, kita punya objek berikut:

TEXT
s3://demo-toko-id/produk/2026/sepatu-hitam.jpg

Bagian-bagiannya adalah:

TEXT
Bucket: demo-toko-id
Key: produk/2026/sepatu-hitam.jpg
Object: isi berkas sepatu-hitam.jpg

Walaupun key tersebut terlihat seperti struktur folder, S3 sebenarnya memakai ruang nama yang datar. Tanda garis miring hanya membantu console dan aplikasi menampilkan key seolah-olah berbentuk folder.

S3 mendukung objek dari 0 byte sampai 5 TB. Untuk objek besar, terutama di atas 5 GB, unggahan multipart perlu dipakai agar berkas dibagi menjadi beberapa bagian dan dapat dikirim secara paralel.

Kelebihan dan keterbatasan Amazon S3

S3 kuat, tetapi bukan jawaban untuk semua jenis penyimpanan. Mengetahui batasnya sejak awal bisa mencegah arsitektur yang mahal atau rumit.

Kelebihan utama

  • Kapasitas elastis: tidak perlu menyiapkan ukuran disk di awal.
  • Daya tahan tinggi: S3 dirancang untuk daya tahan data 99,999999999%, atau sebelas angka sembilan.
  • Keamanan bawaan: objek baru dienkripsi di sisi server secara default.
  • Akses terkontrol: izin dapat diatur melalui IAM policy, bucket policy, access point, dan presigned URL.
  • Pilihan biaya: tersedia beberapa storage class untuk pola akses yang berbeda.
  • Integrasi luas: dapat dipakai bersama CloudFront, Lambda, Athena, Glue, EMR, SageMaker, dan layanan AWS lainnya.
  • Otomatisasi: lifecycle rule dapat memindahkan atau menghapus data berdasarkan umur objek.
  • Konsistensi kuat: pembacaan setelah penulisan, penimpaan, atau penghapusan akan melihat keadaan terbaru.

Keterbatasan yang perlu diperhatikan

  • S3 bukan file system POSIX biasa.
  • S3 bukan database relasional.
  • Mengubah sebagian kecil isi objek biasanya berarti mengunggah ulang objek.
  • Biaya bukan hanya berasal dari penyimpanan.
  • Data keluar ke internet dapat menjadi komponen biaya besar.
  • Storage class arsip memiliki waktu pemulihan dan durasi penyimpanan minimum.
  • Aplikasi yang membutuhkan latensi sangat rendah untuk perubahan kecil dan acak mungkin lebih cocok memakai block storage atau database.

Siapa yang paling cocok memakai S3?

Amazon S3 cocok untuk:

  • Aplikasi web dan mobile yang menyimpan unggahan pengguna.
  • Toko daring yang menyimpan foto serta video produk.
  • Sistem pencadangan dan pemulihan.
  • Data lake untuk analitik.
  • Distribusi aset statis.
  • Arsip dokumen jangka panjang.
  • Log aplikasi dan hasil ekspor laporan.
  • Dataset machine learning dan AI.
  • Penyimpanan objek untuk arsitektur serverless.

S3 sebaiknya tidak dijadikan pilihan utama untuk:

  • Disk sistem operasi.
  • Database transaksional yang menulis blok kecil secara acak.
  • Aplikasi yang wajib memakai locking dan semantik file system penuh.
  • Berkas sementara berukuran sangat kecil dengan jutaan operasi per detik tanpa perhitungan biaya request.
  • Sistem yang tidak bisa menoleransi akses berbasis API.

Perbandingan Amazon S3 dengan penyimpanan file, block, dan database

Pilihan Cara menyimpan data Cocok untuk Kelebihan Keterbatasan
Amazon S3 Objek dengan key dan metadata Gambar, video, backup, log, data lake Sangat elastis dan mudah diintegrasikan Bukan file system POSIX
Amazon EBS Block storage Disk EC2 dan database Latensi rendah dan mendukung perubahan blok Terikat pada kapasitas serta Availability Zone
Amazon EFS Shared file system Aplikasi yang butuh folder bersama Semantik file system dan akses banyak mesin Biaya per GB biasanya lebih tinggi
Database Record, tabel, dokumen, atau key-value Transaksi dan pencarian terstruktur Query, indeks, dan transaksi Tidak ideal untuk menyimpan berkas besar dalam jumlah masif
Disk lokal File pada satu server Cache dan data sementara Cepat dan sederhana Sulit dibagikan serta rawan hilang saat server diganti

Untuk aplikasi toko daring, pola yang sehat biasanya seperti ini:

  • Informasi produk disimpan di database.
  • Foto produk disimpan di S3.
  • URL atau key foto disimpan di database.
  • CloudFront dipakai untuk mengirim gambar ke pelanggan.
  • Berkas asli tetap privat di S3.

Getting Started: prasyarat sebelum memakai Amazon S3

Teman-Teman membutuhkan:

  1. Akun AWS aktif.
  2. Pengguna atau role IAM dengan izin yang sesuai.
  3. AWS CLI versi 2.
  4. Python 3.10 atau yang lebih baru untuk contoh program.
  5. Pustaka boto3.
  6. Terminal seperti PowerShell, Command Prompt, Terminal macOS, atau shell Linux.
  7. Nama bucket yang unik.
  8. Region AWS yang akan dipakai.

Periksa instalasi AWS CLI:

BASH
aws --version

Contoh keluaran:

TEXT
aws-cli/2.27.18 Python/3.13.3 Linux/6.8.0 exe/x86_64

Periksa Python:

BASH
python --version

Contoh keluaran:

TEXT
Python 3.12.4

Instal boto3:

BASH
python -m pip install boto3

Contoh keluaran:

TEXT
Successfully installed boto3-1.38.0 botocore-1.38.0

Jika bekerja dalam proyek, gunakan virtual environment supaya dependensi tidak bercampur dengan proyek lain:

BASH
python -m venv .venv

Aktifkan di Linux atau macOS:

BASH
source .venv/bin/activate

Aktifkan di Windows PowerShell:

POWERSHELL
.venv\Scripts\Activate.ps1

Lalu pasang boto3:

BASH
python -m pip install boto3

Mengapa langkah ini penting? AWS CLI membantu menguji konfigurasi tanpa menulis program. Setelah akses terbukti benar lewat CLI, masalah di kode Python jadi lebih mudah dipisahkan dari masalah kredensial atau jaringan.

Step 1 — Pilih Region AWS dan strategi penempatan data

Region menentukan lokasi utama bucket, latensi akses, ketersediaan fitur, kebutuhan kepatuhan, dan sebagian struktur biaya.

Untuk pengguna di Indonesia, pilihan yang sering dipertimbangkan meliputi:

  • ap-southeast-3 untuk Asia Pacific Jakarta.
  • ap-southeast-1 untuk Asia Pacific Singapore.
  • Region lain jika aplikasi atau sistem utama memang berada di sana.

Jika server aplikasi berjalan di Jakarta, bucket di region yang sama biasanya memberi jalur akses lebih dekat dan menghindari transfer lintas region yang tidak perlu.

Gunakan perintah berikut untuk melihat region aktif pada profil CLI:

BASH
aws configure get region

Atur region default:

BASH
aws configure set region ap-southeast-3

Periksa kembali:

BASH
aws configure list

Contoh keluaran:

TEXT
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     ****************ABCD shared-credentials-file
secret_key     ****************WXYZ shared-credentials-file
    region           ap-southeast-3      config-file

Cara menentukan region

Pertimbangkan lima hal:

  1. Lokasi pengguna dan aplikasi
    Letakkan data dekat dengan komputasi yang paling sering mengaksesnya.

  2. Kebutuhan residensi data
    Beberapa organisasi memiliki aturan internal atau kontraktual soal lokasi penyimpanan.

  3. Ketersediaan layanan
    Tidak semua fitur baru langsung tersedia di semua region.

  4. Biaya
    Harga penyimpanan dan transfer dapat berbeda antarregion.

  5. Pemulihan bencana
    Jika perlu salinan lintas region, hitung biaya penyimpanan kedua, request replikasi, dan transfer data.

Kesalahan yang sering terjadi

Masalah: bucket dibuat di Singapore, sedangkan aplikasi berjalan di Jakarta tanpa alasan jelas.

Dampak: akses harus melewati region berbeda dan mungkin menambah biaya transfer serta latensi.

Perbaikan: tempatkan bucket dan komputasi pada region yang sama, kecuali ada kebutuhan bisnis atau pemulihan bencana yang membenarkan pemisahan.

Step 2 — Konfigurasikan kredensial AWS dengan aman

Jangan menulis access key langsung di source code. Kunci yang masuk ke Git sering menjadi pintu masuk insiden keamanan dan tagihan tak terduga.

Untuk komputer pengembangan, konfigurasi dasar dapat dilakukan dengan:

BASH
aws configure

Masukkan nilai yang diminta:

TEXT
AWS Access Key ID [None]: AKIA...
AWS Secret Access Key [None]: ********
Default region name [None]: ap-southeast-3
Default output format [None]: json

Uji identitas yang sedang digunakan:

BASH
aws sts get-caller-identity

Contoh keluaran:

JSON
{
  "UserId": "AIDAEXAMPLEUSER",
  "Account": "123456789012",
  "Arn": "arn:aws:iam::123456789012:user/s3-tutorial"
}

Mengapa langkah ini penting? Perintah tersebut memastikan CLI benar-benar memakai akun dan identitas yang Teman-Teman maksud. Banyak kesalahan terjadi karena terminal masih menunjuk ke profil akun lain.

Gunakan named profile untuk beberapa lingkungan

Buat profil khusus:

BASH
aws configure --profile s3-lab

Pakai profil tersebut:

BASH
aws sts get-caller-identity --profile s3-lab

Atau melalui variabel lingkungan:

BASH
export AWS_PROFILE=s3-lab

Di PowerShell:

POWERSHELL
$env:AWS_PROFILE = "s3-lab"

Praktik aman untuk produksi

Untuk workload di AWS, gunakan IAM role:

  • EC2 instance profile untuk aplikasi di EC2.
  • Task role untuk ECS.
  • Execution role atau function role untuk Lambda.
  • IRSA atau Pod Identity untuk workload di EKS.
  • IAM Identity Center untuk akses manusia.

Dengan role, aplikasi memperoleh kredensial sementara. Teman-Teman tidak perlu menyimpan access key permanen di server.

Kebijakan IAM minimum untuk tutorial

Ganti nama-bucket-unik-anda dengan bucket yang akan digunakan:

JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "ListTutorialBucket",
      "Effect": "Allow",
      "Action": [
        "s3:ListBucket",
        "s3:GetBucketLocation"
      ],
      "Resource": "arn:aws:s3:::nama-bucket-unik-anda"
    },
    {
      "Sid": "ManageTutorialObjects",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject"
      ],
      "Resource": "arn:aws:s3:::nama-bucket-unik-anda/*"
    }
  ]
}

Kebijakan ini sengaja dibatasi ke satu bucket. Memberi s3:* untuk semua resource memang lebih cepat saat uji coba, tetapi terlalu luas untuk sistem nyata.

Step 3 — Buat bucket Amazon S3

Nama bucket harus unik dalam namespace S3 yang berlaku. Pilih nama yang stabil karena nama bucket sering muncul di konfigurasi, log, dan alamat endpoint.

Contoh pola nama:

TEXT
acme-media-prod-id-123456

Hindari memasukkan:

  • Nama pengguna pribadi.
  • Alamat email.
  • Data pelanggan.
  • Informasi rahasia.
  • Nama yang terlalu umum seperti images atau backup.

Simpan nama bucket dalam variabel:

BASH
BUCKET_NAME="acme-s3-tutorial-id-123456"
AWS_REGION="ap-southeast-3"

Buat bucket di region Jakarta:

BASH
aws s3api create-bucket \
  --bucket "$BUCKET_NAME" \
  --region "$AWS_REGION" \
  --create-bucket-configuration LocationConstraint="$AWS_REGION"

Contoh keluaran:

JSON
{
  "Location": "http://acme-s3-tutorial-id-123456.s3.amazonaws.com/"
}

Periksa bucket:

BASH
aws s3api head-bucket --bucket "$BUCKET_NAME"

Jika berhasil, perintah biasanya tidak menampilkan keluaran dan mengembalikan exit code 0.

Lihat daftar bucket:

BASH
aws s3 ls

Contoh keluaran:

TEXT
2026-07-11 15:12:44 acme-s3-tutorial-id-123456

Catatan khusus us-east-1

Pembuatan bucket di us-east-1 tidak memakai parameter LocationConstraint:

BASH
aws s3api create-bucket \
  --bucket "$BUCKET_NAME" \
  --region us-east-1

Error: BucketAlreadyExists

Contoh:

TEXT
An error occurred (BucketAlreadyExists) when calling the CreateBucket operation:
The requested bucket name is not available.

Penyebab: nama tersebut sudah dipakai akun lain.

Solusi: tambahkan nama organisasi, lingkungan, region, atau angka acak:

TEXT
acme-media-dev-ap-southeast-3-839201

Error: IllegalLocationConstraintException

Penyebab: parameter region tidak cocok dengan konfigurasi pembuatan bucket.

Solusi: pastikan nilai --region dan LocationConstraint sama:

BASH
aws s3api create-bucket \
  --bucket "$BUCKET_NAME" \
  --region ap-southeast-3 \
  --create-bucket-configuration LocationConstraint=ap-southeast-3

Step 4 — Pastikan bucket tetap privat

Bucket sebaiknya privat secara default. Akses publik hanya dibuka jika kebutuhan produk memang mengharuskannya dan risikonya sudah dipahami.

Aktifkan seluruh pengaturan Block Public Access:

BASH
aws s3api put-public-access-block \
  --bucket "$BUCKET_NAME" \
  --public-access-block-configuration \
  "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"

Periksa hasilnya:

BASH
aws s3api get-public-access-block --bucket "$BUCKET_NAME"

Keluaran yang diharapkan:

JSON
{
  "PublicAccessBlockConfiguration": {
    "BlockPublicAcls": true,
    "IgnorePublicAcls": true,
    "BlockPublicPolicy": true,
    "RestrictPublicBuckets": true
  }
}

Aktifkan Bucket Owner Enforced agar ACL dinonaktifkan:

BASH
aws s3api put-bucket-ownership-controls \
  --bucket "$BUCKET_NAME" \
  --ownership-controls \
  'Rules=[{ObjectOwnership=BucketOwnerEnforced}]'

Periksa konfigurasi:

BASH
aws s3api get-bucket-ownership-controls --bucket "$BUCKET_NAME"

Keluaran:

JSON
{
  "OwnershipControls": {
    "Rules": [
      {
        "ObjectOwnership": "BucketOwnerEnforced"
      }
    ]
  }
}

Mengapa langkah ini penting? ACL adalah mekanisme izin lama yang mudah menambah kerumitan. Untuk banyak aplikasi modern, IAM policy dan bucket policy lebih mudah diaudit.

Step 5 — Unggah dan unduh objek lewat AWS CLI

Buat contoh berkas:

BASH
mkdir -p data
echo "Laporan penjualan Juli 2026" > data/laporan.txt

Unggah ke S3:

BASH
aws s3 cp data/laporan.txt \
  "s3://$BUCKET_NAME/laporan/2026/07/laporan.txt"

Keluaran:

TEXT
upload: data/laporan.txt to s3://acme-s3-tutorial-id-123456/laporan/2026/07/laporan.txt

Lihat daftar objek:

BASH
aws s3 ls "s3://$BUCKET_NAME/laporan/2026/07/"

Keluaran:

TEXT
2026-07-11 15:25:03         30 laporan.txt

Unduh kembali:

BASH
mkdir -p hasil
aws s3 cp \
  "s3://$BUCKET_NAME/laporan/2026/07/laporan.txt" \
  hasil/laporan.txt

Keluaran:

TEXT
download: s3://acme-s3-tutorial-id-123456/laporan/2026/07/laporan.txt to hasil/laporan.txt

Periksa isi:

BASH
cat hasil/laporan.txt

Keluaran:

TEXT
Laporan penjualan Juli 2026

Mengapa struktur key perlu dirancang?

Key yang jelas memudahkan:

  • Pencarian berdasarkan prefix.
  • Pengaturan lifecycle.
  • Pembatasan izin berdasarkan area.
  • Analisis biaya.
  • Pengelolaan data antarlingkungan.

Contoh struktur yang sehat:

TEXT
uploads/{customer_id}/{year}/{month}/{uuid}-{filename}

Contoh konkret:

TEXT
uploads/customer-873/2026/07/550e8400-e29b-41d4-a716-446655440000-invoice.pdf

Jangan mengandalkan nama berkas asli sebagai key tunggal. Dua pengguna bisa mengunggah foto.jpg dan saling menimpa objek jika key-nya sama.

Unggah seluruh direktori

BASH
aws s3 cp ./assets "s3://$BUCKET_NAME/assets/" --recursive

Sinkronkan direktori

BASH
aws s3 sync ./assets "s3://$BUCKET_NAME/assets/"

sync hanya mengirim berkas yang berbeda atau belum tersedia. Ini cocok untuk kumpulan aset, tetapi tetap periksa opsi penghapusan sebelum dipakai.

Perintah berikut akan menghapus objek di tujuan yang tidak tersedia di sumber:

BASH
aws s3 sync ./assets "s3://$BUCKET_NAME/assets/" --delete

Gunakan --dryrun lebih dulu:

BASH
aws s3 sync ./assets "s3://$BUCKET_NAME/assets/" --delete --dryrun

Pelajaran yang sering mahal: satu opsi --delete yang dijalankan ke bucket produksi dapat menghapus ribuan objek. MUGHU lebih memilih menjadikan --dryrun sebagai langkah wajib dalam prosedur operasional, bukan sekadar saran.

Step 6 — Pahami metadata, content type, dan cache control

Browser dan CDN perlu mengetahui tipe isi objek. Jika gambar diunggah dengan Content-Type yang salah, browser bisa mengunduhnya sebagai berkas biasa atau menampilkannya dengan perilaku yang tidak diinginkan.

Unggah gambar dengan metadata:

BASH
aws s3 cp ./assets/logo.png \
  "s3://$BUCKET_NAME/assets/logo.png" \
  --content-type "image/png" \
  --cache-control "public,max-age=31536000,immutable"

Periksa metadata:

BASH
aws s3api head-object \
  --bucket "$BUCKET_NAME" \
  --key "assets/logo.png"

Contoh keluaran:

JSON
{
  "ContentLength": 24518,
  "ContentType": "image/png",
  "CacheControl": "public,max-age=31536000,immutable",
  "ServerSideEncryption": "AES256"
}

Kapan memakai cache satu tahun?

Gunakan cache panjang jika nama berkas berubah saat isinya berubah:

TEXT
logo.8f4c21a.png

Jangan memakai cache sangat panjang untuk nama yang isinya sering ditimpa:

TEXT
logo.png

Jika isi logo.png diganti tetapi browser menyimpan versi lama selama setahun, pengguna bisa terus melihat gambar lama.

Tambahkan metadata khusus

BASH
aws s3 cp data/laporan.txt \
  "s3://$BUCKET_NAME/laporan/laporan-metadata.txt" \
  --metadata "department=finance,classification=internal"

Periksa:

BASH
aws s3api head-object \
  --bucket "$BUCKET_NAME" \
  --key "laporan/laporan-metadata.txt"

Metadata khusus berguna untuk konteks tambahan, tetapi bukan pengganti database jika aplikasi perlu menjalankan query kompleks.

Step 7 — Akses Amazon S3 memakai Python dan Boto3

Buat berkas s3_tutorial.py:

PYTHON
from pathlib import Path

import boto3
from botocore.exceptions import ClientError

BUCKET_NAME = "acme-s3-tutorial-id-123456"
AWS_REGION = "ap-southeast-3"

s3 = boto3.client("s3", region_name=AWS_REGION)

def upload_file(local_path: str, object_key: str) -> None:
    path = Path(local_path)

    if not path.exists():
        raise FileNotFoundError(f"Berkas tidak ditemukan: {path}")

    extra_args = {
        "ContentType": "text/plain; charset=utf-8",
        "Metadata": {
            "source": "python-tutorial",
            "classification": "internal",
        },
    }

    s3.upload_file(
        Filename=str(path),
        Bucket=BUCKET_NAME,
        Key=object_key,
        ExtraArgs=extra_args,
    )

    print(f"Berhasil mengunggah s3://{BUCKET_NAME}/{object_key}")

if __name__ == "__main__":
    upload_file(
        local_path="data/laporan.txt",
        object_key="python/2026/07/laporan.txt",
    )

Jalankan:

BASH
python s3_tutorial.py

Keluaran:

TEXT
Berhasil mengunggah s3://acme-s3-tutorial-id-123456/python/2026/07/laporan.txt

Mengapa memakai upload_file? Metode ini menyediakan abstraksi transfer yang lebih nyaman dan dapat menangani multipart upload untuk berkas besar. Untuk data kecil yang sudah berada di memori, put_object juga berguna.

Mengunggah data langsung dari memori

PYTHON
import json

import boto3

BUCKET_NAME = "acme-s3-tutorial-id-123456"

s3 = boto3.client("s3", region_name="ap-southeast-3")

payload = {
    "order_id": "ORD-2026-0001",
    "city": "Jakarta",
    "total": 275000,
}

response = s3.put_object(
    Bucket=BUCKET_NAME,
    Key="orders/2026/07/ORD-2026-0001.json",
    Body=json.dumps(payload, ensure_ascii=False).encode("utf-8"),
    ContentType="application/json; charset=utf-8",
)

print(response["ETag"])

Contoh keluaran:

TEXT
"6f5902ac237024bdd0c176cb93063dc4"

Jangan menganggap ETag selalu sama dengan MD5. Pada multipart upload dan beberapa konfigurasi enkripsi, bentuk ETag dapat berbeda.

Membaca objek dari S3

PYTHON
import json

import boto3
from botocore.exceptions import ClientError

BUCKET_NAME = "acme-s3-tutorial-id-123456"
OBJECT_KEY = "orders/2026/07/ORD-2026-0001.json"

s3 = boto3.client("s3", region_name="ap-southeast-3")

try:
    response = s3.get_object(
        Bucket=BUCKET_NAME,
        Key=OBJECT_KEY,
    )

    raw_data = response["Body"].read()
    payload = json.loads(raw_data.decode("utf-8"))

    print(payload)

except ClientError as error:
    code = error.response["Error"]["Code"]

    if code in {"NoSuchKey", "404"}:
        print(f"Objek tidak ditemukan: {OBJECT_KEY}")
    elif code == "AccessDenied":
        print("Akses ditolak. Periksa IAM policy dan bucket policy.")
    else:
        raise

Keluaran:

TEXT
{'order_id': 'ORD-2026-0001', 'city': 'Jakarta', 'total': 275000}

Unduh objek ke berkas lokal

PYTHON
import boto3

BUCKET_NAME = "acme-s3-tutorial-id-123456"

s3 = boto3.client("s3", region_name="ap-southeast-3")

s3.download_file(
    Bucket=BUCKET_NAME,
    Key="python/2026/07/laporan.txt",
    Filename="hasil/laporan-python.txt",
)

print("Unduhan selesai")

Keluaran:

TEXT
Unduhan selesai

Menampilkan objek berdasarkan prefix

PYTHON
import boto3

BUCKET_NAME = "acme-s3-tutorial-id-123456"

s3 = boto3.client("s3", region_name="ap-southeast-3")
paginator = s3.get_paginator("list_objects_v2")

for page in paginator.paginate(
    Bucket=BUCKET_NAME,
    Prefix="orders/2026/07/",
):
    for item in page.get("Contents", []):
        print(item["Key"], item["Size"])

Contoh keluaran:

TEXT
orders/2026/07/ORD-2026-0001.json 77
orders/2026/07/ORD-2026-0002.json 81

Mengapa paginator penting? Satu respons list_objects_v2 tidak mengembalikan daftar tanpa batas. Jika aplikasi hanya memanggil API sekali, objek setelah halaman pertama bisa tidak diproses.

Step 8 — Buat presigned URL untuk akses sementara

Bucket privat tidak berarti aplikasi harus mengunduh semua berkas melalui server sendiri. Aplikasi dapat membuat presigned URL, yaitu alamat sementara yang memberi izin untuk operasi tertentu.

Presigned URL untuk unduhan

Buat presigned_download.py:

PYTHON
import boto3
from botocore.exceptions import ClientError

BUCKET_NAME = "acme-s3-tutorial-id-123456"
OBJECT_KEY = "assets/logo.png"

s3 = boto3.client("s3", region_name="ap-southeast-3")

try:
    url = s3.generate_presigned_url(
        ClientMethod="get_object",
        Params={
            "Bucket": BUCKET_NAME,
            "Key": OBJECT_KEY,
        },
        ExpiresIn=900,
    )

    print(url)

except ClientError as error:
    print(f"Gagal membuat URL: {error}")

Jalankan:

BASH
python presigned_download.py

Keluaran akan menyerupai:

TEXT
https://acme-s3-tutorial-id-123456.s3.ap-southeast-3.amazonaws.com/assets/logo.png? X-Amz-Algorithm=...

URL berlaku selama 900 detik atau 15 menit.

Mengapa presigned URL penting?

Tanpa pola ini, aplikasi biasanya melakukan alur berikut:

  1. Pengguna meminta berkas.
  2. Server mengunduh berkas dari S3.
  3. Server meneruskan seluruh isi ke pengguna.

Alur tersebut membuat bandwidth dan koneksi server aplikasi bekerja dua kali. Dengan presigned URL, server hanya memeriksa otorisasi dan membuat URL. Pengguna kemudian mengambil objek langsung dari S3.

Presigned URL untuk unggahan

PYTHON
import boto3

BUCKET_NAME = "acme-s3-tutorial-id-123456"

s3 = boto3.client("s3", region_name="ap-southeast-3")

url = s3.generate_presigned_url(
    ClientMethod="put_object",
    Params={
        "Bucket": BUCKET_NAME,
        "Key": "uploads/customer-873/profile.jpg",
        "ContentType": "image/jpeg",
    },
    ExpiresIn=600,
)

print(url)

Unggah dengan curl:

BASH
curl -X PUT \
  -H "Content-Type: image/jpeg" \
  --upload-file profile.jpg \
  "URL_PRESIGNED_DARI_PROGRAM"

Keluaran yang berhasil biasanya tidak berisi body dan mengembalikan status HTTP 200.

Error: SignatureDoesNotMatch

Penyebab umum:

  • Header Content-Type saat upload berbeda dari yang ditandatangani.
  • URL sudah kedaluwarsa.
  • URL terpotong saat dikirim.
  • Jam sistem klien terlalu meleset.
  • Parameter URL berubah.
  • Kredensial pembuat URL sudah tidak berlaku.

Jika URL dibuat dengan:

PYTHON
"ContentType": "image/jpeg"

maka request harus mengirim:

HTTP
Content-Type: image/jpeg

Bukan image/jpg, application/octet-stream, atau tanpa header.

Batasi ukuran unggahan dengan presigned POST

Presigned PUT sederhana tidak menetapkan batas ukuran melalui policy. Untuk formulir unggahan yang perlu batas ukuran, gunakan presigned POST:

PYTHON
import boto3

BUCKET_NAME = "acme-s3-tutorial-id-123456"

s3 = boto3.client("s3", region_name="ap-southeast-3")

response = s3.generate_presigned_post(
    Bucket=BUCKET_NAME,
    Key="uploads/customer-873/${filename}",
    Fields={
        "Content-Type": "image/jpeg",
    },
    Conditions=[
        {"Content-Type": "image/jpeg"},
        ["content-length-range", 1, 5 * 1024 * 1024],
    ],
    ExpiresIn=600,
)

print(response)

Policy tersebut membatasi berkas antara 1 byte dan 5 MB.

Di sistem nyata, validasi tidak berhenti pada ekstensi dan Content-Type. Periksa isi berkas setelah upload, gunakan pemindaian malware jika dibutuhkan, dan pisahkan area karantina dari area publik.

Step 9 — Atur CORS untuk unggahan dari browser

CORS diperlukan ketika halaman web pada satu origin mengakses S3 melalui browser.

Misalnya:

TEXT
Aplikasi: https://app.example.id
Bucket: https://bucket-name.s3.ap-southeast-3.amazonaws.com

Buat cors.json:

JSON
{
  "CORSRules": [
    {
      "AllowedOrigins": [
        "https://app.example.id"
      ],
      "AllowedMethods": [
        "GET",
        "PUT",
        "HEAD"
      ],
      "AllowedHeaders": [
        "Content-Type",
        "x-amz-date",
        "x-amz-content-sha256",
        "authorization"
      ],
      "ExposeHeaders": [
        "ETag"
      ],
      "MaxAgeSeconds": 3600
    }
  ]
}

Terapkan:

BASH
aws s3api put-bucket-cors \
  --bucket "$BUCKET_NAME" \
  --cors-configuration file://cors.json

Periksa:

BASH
aws s3api get-bucket-cors --bucket "$BUCKET_NAME"

Jangan memakai wildcard tanpa alasan

Konfigurasi berikut terlalu longgar untuk banyak sistem:

JSON
{
  "AllowedOrigins": ["*"],
  "AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
  "AllowedHeaders": ["*"]
}

CORS bukan mekanisme otorisasi utama, tetapi konfigurasi yang terlalu luas memperbesar permukaan penyalahgunaan. Batasi origin, metode, dan header sesuai alur aplikasi.

Error CORS di browser

Pesan yang sering terlihat:

TEXT
Access to fetch at 'https://...' from origin 'https://app.example.id'
has been blocked by CORS policy.

Periksa:

  • Origin harus sama persis, termasuk skema https.
  • Method harus masuk dalam AllowedMethods.
  • Header request harus diizinkan.
  • Preflight OPTIONS harus mendapat respons yang sesuai.
  • Redirect region dapat mengganggu request.
  • Presigned URL harus menunjuk ke endpoint region yang benar.

Gunakan Developer Tools pada browser untuk melihat request OPTIONS dan respons S3.

Step 10 — Aktifkan versioning untuk melindungi objek

Versioning menyimpan beberapa versi dari key yang sama. Jika objek ditimpa atau dihapus, versi lama masih dapat dipulihkan.

Aktifkan:

BASH
aws s3api put-bucket-versioning \
  --bucket "$BUCKET_NAME" \
  --versioning-configuration Status=Enabled

Periksa:

BASH
aws s3api get-bucket-versioning --bucket "$BUCKET_NAME"

Keluaran:

JSON
{
  "Status": "Enabled"
}

Unggah versi pertama:

BASH
echo "Versi pertama" > data/kontrak.txt

aws s3 cp data/kontrak.txt \
  "s3://$BUCKET_NAME/dokumen/kontrak.txt"

Unggah versi kedua:

BASH
echo "Versi kedua" > data/kontrak.txt

aws s3 cp data/kontrak.txt \
  "s3://$BUCKET_NAME/dokumen/kontrak.txt"

Lihat semua versi:

BASH
aws s3api list-object-versions \
  --bucket "$BUCKET_NAME" \
  --prefix "dokumen/kontrak.txt"

Contoh keluaran ringkas:

JSON
{
  "Versions": [
    {
      "Key": "dokumen/kontrak.txt",
      "VersionId": "new-version-id",
      "IsLatest": true
    },
    {
      "Key": "dokumen/kontrak.txt",
      "VersionId": "old-version-id",
      "IsLatest": false
    }
  ]
}

Unduh versi tertentu:

BASH
aws s3api get-object \
  --bucket "$BUCKET_NAME" \
  --key "dokumen/kontrak.txt" \
  --version-id "old-version-id" \
  hasil/kontrak-versi-lama.txt

Versioning bukan backup lengkap

Versioning membantu mengatasi:

  • Penimpaan tidak sengaja.
  • Penghapusan objek.
  • Kebutuhan melihat versi terdahulu.

Namun, versioning berada di bucket yang sama. Untuk kebutuhan pemulihan yang lebih kuat, pertimbangkan:

  • Cross-Region Replication.
  • Replikasi ke akun AWS terpisah.
  • S3 Object Lock.
  • AWS Backup.
  • Pemisahan kewenangan pengelola produksi dan cadangan.

Biaya versioning

Setiap versi memakai ruang penyimpanan. Objek 500 MB yang ditimpa sepuluh kali dapat menghasilkan beberapa gigabyte versi tersimpan.

Gunakan lifecycle untuk menghapus versi noncurrent yang tidak lagi diperlukan.

Step 11 — Pilih storage class Amazon S3 yang tepat

Harga S3 mengikuti beberapa komponen:

  • Kapasitas penyimpanan.
  • Jumlah dan jenis request.
  • Pengambilan data dari kelas tertentu.
  • Transfer data.
  • Replikasi.
  • Monitoring dan fitur pengelolaan.
  • Transformasi serta query tertentu.

Rincian tarif berubah menurut region dan volume. Gunakan halaman harga resmi Amazon S3 sebelum membuat proyeksi biaya.

Perbandingan storage class

Storage class Pola akses Kecepatan akses Durasi minimum Biaya retrieval Cocok untuk
S3 Standard Sering dan aktif Milidetik Tidak ada Tidak ada Aplikasi, konten aktif, data lake
S3 Intelligent-Tiering Tidak diketahui atau berubah Milidetik hingga arsip Bergantung tier Tidak ada untuk retrieval standar Data dengan pola akses sulit diprediksi
S3 Standard-IA Jarang, tetapi harus cepat tersedia Milidetik 30 hari Ada Backup aktif dan disaster recovery
S3 One Zone-IA Jarang dan bisa dibuat ulang Milidetik 30 hari Ada Salinan sekunder dan data nonkritis
S3 Glacier Instant Retrieval Sangat jarang, tetapi harus langsung tersedia Milidetik 90 hari Ada Arsip yang sesekali perlu akses cepat
S3 Glacier Flexible Retrieval Arsip Menit sampai jam 90 hari Bergantung metode Backup dan arsip dengan pemulihan terencana
S3 Glacier Deep Archive Hampir tidak pernah diakses Jam 180 hari Ada Retensi jangka panjang dan kepatuhan
S3 Express One Zone Sangat aktif dan sensitif terhadap latensi Milidetik satu digit Periksa tarif Sesuai model kelas Analitik dan pemrosesan intensif di satu AZ

Rekomendasi berdasarkan penggunaan

Gunakan S3 Standard jika:

  • Data dibaca setiap hari.
  • Pola akses aktif.
  • Aplikasi sensitif terhadap keterlambatan retrieval.
  • Teman-Teman belum memiliki bukti bahwa tier yang lebih dingin akan lebih murah.

Gunakan Intelligent-Tiering jika:

  • Pola akses sulit diprediksi.
  • Sebagian objek aktif, lalu mendadak jarang dibaca.
  • Tim tidak ingin mengelola transisi manual.
  • Ukuran dan jumlah objek cukup layak dibanding biaya monitoring per objek.

Gunakan Standard-IA jika:

  • Data bertahan lebih dari 30 hari.
  • Akses jarang, tetapi harus tetap cepat.
  • Biaya retrieval dapat diperkirakan.

Gunakan One Zone-IA jika:

  • Data dapat dibuat ulang.
  • Kehilangan satu Availability Zone dapat ditoleransi.
  • Data bukan satu-satunya salinan.

Gunakan Glacier Instant Retrieval jika:

  • Data jarang dibuka.
  • Akses sesekali tetap harus berlangsung dalam milidetik.
  • Durasi penyimpanan lebih dari 90 hari.

Gunakan Glacier Flexible Retrieval jika:

  • Pemulihan dalam menit atau jam masih diterima.
  • Data berupa arsip atau cadangan.
  • Prosedur pemulihan sudah diuji.

Gunakan Deep Archive jika:

  • Data disimpan bertahun-tahun.
  • Akses hanya terjadi untuk audit atau kejadian khusus.
  • Waktu pemulihan berjam-jam bisa diterima.

Jebakan objek kecil

Standard-IA, One Zone-IA, dan beberapa kelas Glacier memiliki ukuran objek minimum yang dapat ditagihkan. Menyimpan jutaan objek berukuran 2 KB langsung ke kelas dengan minimum billable 128 KB bisa membuat penghematan yang dibayangkan tidak terjadi.

Untuk data kecil:

  • Gabungkan record ke berkas yang lebih besar.
  • Gunakan format seperti Parquet untuk analitik.
  • Hitung biaya request dan minimum object size.
  • Jangan melihat harga per GB saja.

Step 12 — Terapkan lifecycle policy untuk mengendalikan biaya

Lifecycle policy memindahkan atau menghapus objek berdasarkan umur. Ini salah satu fitur S3 yang paling berguna untuk menjaga biaya tetap masuk akal.

Buat lifecycle.json:

JSON
{
  "Rules": [
    {
      "ID": "ArchiveLogs",
      "Status": "Enabled",
      "Filter": {
        "Prefix": "logs/"
      },
      "Transitions": [
        {
          "Days": 30,
          "StorageClass": "STANDARD_IA"
        },
        {
          "Days": 90,
          "StorageClass": "GLACIER"
        },
        {
          "Days": 365,
          "StorageClass": "DEEP_ARCHIVE"
        }
      ],
      "Expiration": {
        "Days": 2555
      },
      "NoncurrentVersionTransitions": [
        {
          "NoncurrentDays": 30,
          "StorageClass": "STANDARD_IA"
        }
      ],
      "NoncurrentVersionExpiration": {
        "NoncurrentDays": 365
      },
      "AbortIncompleteMultipartUpload": {
        "DaysAfterInitiation": 7
      }
    }
  ]
}

Terapkan:

BASH
aws s3api put-bucket-lifecycle-configuration \
  --bucket "$BUCKET_NAME" \
  --lifecycle-configuration file://lifecycle.json

Periksa:

BASH
aws s3api get-bucket-lifecycle-configuration \
  --bucket "$BUCKET_NAME"

Mengapa setiap bagian penting?

  • Filter. Prefix memastikan aturan hanya berlaku pada logs/.
  • Transitions memindahkan objek ke kelas yang lebih murah.
  • Expiration menghapus data setelah tujuh tahun.
  • NoncurrentVersionTransitions mengurangi biaya versi lama.
  • NoncurrentVersionExpiration mencegah versi lama menumpuk selamanya.
  • AbortIncompleteMultipartUpload membersihkan bagian upload yang gagal.

Jangan menyalin lifecycle tanpa memahami retensi

Retensi tujuh tahun mungkin cocok untuk satu jenis dokumen, tetapi terlalu lama untuk data sementara dan terlalu singkat untuk aturan tertentu.

Bicarakan dengan pemilik data:

  • Berapa lama data wajib disimpan?
  • Seberapa cepat data harus dipulihkan?
  • Apakah penghapusan harus permanen?
  • Apakah ada legal hold?
  • Siapa yang menyetujui perubahan aturan?
  • Apakah data boleh berpindah ke kelas arsip?

Lifecycle adalah otomatisasi. Kesalahan kecil dapat berjalan pada jutaan objek tanpa meminta konfirmasi satu per satu.

Step 13 — Kelola unggahan berkas besar dengan multipart upload

Multipart upload membagi objek besar menjadi beberapa bagian. Bagian dapat dikirim paralel dan hanya bagian yang gagal yang perlu diulang.

AWS CLI tingkat tinggi akan memakai multipart upload secara otomatis saat dibutuhkan:

BASH
aws s3 cp video-besar.mp4 \
  "s3://$BUCKET_NAME/video/video-besar.mp4"

Untuk melihat multipart upload yang belum selesai:

BASH
aws s3api list-multipart-uploads \
  --bucket "$BUCKET_NAME"

Contoh keluaran:

JSON
{
  "Uploads": [
    {
      "UploadId": "example-upload-id",
      "Key": "video/video-besar.mp4"
    }
  ]
}

Batalkan upload tertentu:

BASH
aws s3api abort-multipart-upload \
  --bucket "$BUCKET_NAME" \
  --key "video/video-besar.mp4" \
  --upload-id "example-upload-id"

Bagian multipart yang belum diselesaikan tetap dapat menimbulkan biaya penyimpanan. Karena itu, lifecycle rule untuk membatalkan upload yang mangkrak sangat disarankan.

Konfigurasi multipart di Python

PYTHON
import boto3
from boto3.s3.transfer import TransferConfig

BUCKET_NAME = "acme-s3-tutorial-id-123456"

s3 = boto3.client("s3", region_name="ap-southeast-3")

transfer_config = TransferConfig(
    multipart_threshold=64 * 1024 * 1024,
    multipart_chunksize=64 * 1024 * 1024,
    max_concurrency=8,
    use_threads=True,
)

s3.upload_file(
    Filename="video-besar.mp4",
    Bucket=BUCKET_NAME,
    Key="video/video-besar.mp4",
    Config=transfer_config,
)

print("Upload selesai")

Nilai part size dan concurrency perlu diuji. Concurrency lebih tinggi tidak selalu lebih cepat jika jaringan, CPU, atau bandwidth sudah penuh.

Step 14 — Tambahkan retry dan penanganan error yang layak

Jaringan dapat terputus, request dapat dibatasi sementara, dan layanan eksternal dapat mengembalikan kesalahan sesaat. Aplikasi produksi harus membedakan error yang bisa dicoba ulang dari error permanen.

Konfigurasikan retry pada Boto3:

PYTHON
import boto3
from botocore.config import Config
from botocore.exceptions import ClientError, EndpointConnectionError

config = Config(
    region_name="ap-southeast-3",
    retries={
        "max_attempts": 8,
        "mode": "adaptive",
    },
    connect_timeout=5,
    read_timeout=60,
)

s3 = boto3.client("s3", config=config)

try:
    response = s3.head_object(
        Bucket="acme-s3-tutorial-id-123456",
        Key="orders/2026/07/ORD-2026-0001.json",
    )

    print(response["ContentLength"])

except EndpointConnectionError:
    print("Tidak dapat tersambung ke endpoint S3.")

except ClientError as error:
    code = error.response["Error"]["Code"]

    if code in {"404", "NoSuchKey"}:
        print("Objek tidak ditemukan.")
    elif code in {"403", "AccessDenied"}:
        print("Akses ditolak.")
    else:
        raise

Jangan mencoba ulang semua error

Error berikut biasanya perlu perbaikan konfigurasi, bukan retry tanpa batas:

  • AccessDenied
  • NoSuchBucket
  • InvalidAccessKeyId
  • SignatureDoesNotMatch
  • InvalidArgument

Retry cocok untuk gangguan sementara, timeout, dan pembatasan sesaat. Tambahkan batas percobaan agar aplikasi tidak menggantung.

Step 15 — Terapkan enkripsi sesuai kebutuhan

S3 mengenkripsi objek baru di sisi server secara default menggunakan kunci yang dikelola S3. Untuk kebutuhan kontrol dan audit lebih rinci, AWS KMS dapat dipakai.

Enkripsi SSE-S3

Unggah dengan SSE-S3:

BASH
aws s3 cp data/laporan.txt \
  "s3://$BUCKET_NAME/secure/laporan.txt" \
  --sse AES256

Enkripsi SSE-KMS

BASH
aws s3 cp data/laporan.txt \
  "s3://$BUCKET_NAME/secure/laporan-kms.txt" \
  --sse aws:kms \
  --sse-kms-key-id "arn:aws:kms:ap-southeast-3:123456789012:key/KEY-ID"

Dengan Python:

PYTHON
import boto3

s3 = boto3.client("s3", region_name="ap-southeast-3")

s3.put_object(
    Bucket="acme-s3-tutorial-id-123456",
    Key="secure/data-rahasia.txt",
    Body=b"Data internal",
    ServerSideEncryption="aws:kms",
    SSEKMSKeyId="arn:aws:kms:ap-southeast-3:123456789012:key/KEY-ID",
)

SSE-S3 versus SSE-KMS

Kriteria SSE-S3 SSE-KMS
Pengelolaan kunci Dikelola S3 Dikelola melalui AWS KMS
Konfigurasi Lebih sederhana Lebih rinci
Audit penggunaan kunci Terbatas dibanding KMS Mendukung audit KMS
Kebijakan kunci Tidak dikelola terpisah Dapat diatur lewat key policy
Biaya tambahan Umumnya tidak ada biaya KMS Ada biaya request dan kunci KMS
Cocok untuk Banyak workload umum Data sensitif dan kontrol kepatuhan lebih ketat

Menggunakan KMS tidak otomatis membuat seluruh arsitektur aman. IAM policy, key policy, bucket policy, logging, dan prosedur rotasi tetap harus benar.

Error: KMS.AccessDeniedException

Periksa dua lapisan izin:

  1. Identitas memiliki izin S3.
  2. Identitas juga diizinkan memakai KMS key.

Contoh izin KMS yang mungkin diperlukan:

JSON
{
  "Effect": "Allow",
  "Action": [
    "kms:Encrypt",
    "kms:Decrypt",
    "kms:GenerateDataKey"
  ],
  "Resource": "arn:aws:kms:ap-southeast-3:123456789012:key/KEY-ID"
}

Step 16 — Buat bucket policy yang membatasi koneksi tidak aman

Bucket policy berikut menolak request yang tidak memakai TLS:

JSON
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyInsecureTransport",
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::acme-s3-tutorial-id-123456",
        "arn:aws:s3:::acme-s3-tutorial-id-123456/*"
      ],
      "Condition": {
        "Bool": {
          "aws:SecureTransport": "false"
        }
      }
    }
  ]
}

Simpan sebagai bucket-policy.json, lalu terapkan:

BASH
aws s3api put-bucket-policy \
  --bucket "$BUCKET_NAME" \
  --policy file://bucket-policy.json

Periksa:

BASH
aws s3api get-bucket-policy \
  --bucket "$BUCKET_NAME"

Mengapa memakai explicit deny? Pernyataan Deny yang cocok akan mengalahkan izin Allow. Ini membantu memastikan request tidak aman tetap ditolak meski ada policy lain yang terlalu longgar.

Sebelum menerapkan bucket policy produksi:

  • Validasi ARN.
  • Uji pada lingkungan nonproduksi.
  • Pastikan role administrasi tetap memiliki akses.
  • Gunakan IAM Access Analyzer.
  • Simpan policy dalam version control.
  • Terapkan lewat Infrastructure as Code jika memungkinkan.

Step 17 — Distribusikan konten dengan CloudFront, bukan bucket publik

Untuk situs atau aplikasi yang melayani gambar ke banyak pengguna, bucket privat di belakang Amazon CloudFront biasanya lebih aman dan fleksibel daripada bucket publik.

Pola arsitekturnya:

TEXT
Pengguna
   |
   v
CloudFront
   |
   v
Bucket S3 privat

Keuntungannya:

  • Konten di-cache dekat dengan pengguna.
  • Bucket tetap privat.
  • Domain khusus dapat dipakai.
  • HTTPS dikelola dengan lebih rapi.
  • AWS WAF dapat ditambahkan.
  • Signed URL atau signed cookie dapat dipakai.
  • Beban request langsung ke origin dapat berkurang.

Untuk toko daring dengan pengguna di Jakarta, Surabaya, Medan, Makassar, dan Denpasar, CDN membantu mengurangi jarak pengiriman konten yang berulang.

Jangan menjadikan static website endpoint S3 sebagai satu-satunya arsitektur produksi untuk aplikasi sensitif. Endpoint website memiliki karakteristik berbeda dari REST endpoint dan perlu dipahami sebelum dipakai.

Step 18 — Hubungkan S3 dengan event-driven processing

S3 dapat mengirim event ketika objek dibuat atau dihapus. Event tersebut bisa diteruskan ke Lambda, SQS, SNS, atau EventBridge sesuai kebutuhan.

Contoh alur pengolahan gambar:

TEXT
Browser mengunggah gambar
        |
        v
S3 bucket area unggahan
        |
        v
S3 Event Notification
        |
        v
SQS
        |
        v
Lambda pemroses
        |
        v
S3 bucket atau prefix hasil

SQS di antara S3 dan Lambda memberi buffer ketika upload melonjak. Pola ini lebih tahan terhadap lonjakan dibanding menganggap semua proses selalu selesai seketika.

Contoh fungsi Lambda Python

PYTHON
import os
import urllib.parse

import boto3

s3 = boto3.client("s3")
DESTINATION_BUCKET = os.environ["DESTINATION_BUCKET"]

def lambda_handler(event, context):
    for record in event.get("Records", []):
        source_bucket = record["s3"]["bucket"]["name"]
        encoded_key = record["s3"]["object"]["key"]
        source_key = urllib.parse.unquote_plus(encoded_key)

        filename = source_key.rsplit("/", 1)[-1]
        destination_key = f"processed/{filename}"

        s3.copy_object(
            CopySource={
                "Bucket": source_bucket,
                "Key": source_key,
            },
            Bucket=DESTINATION_BUCKET,
            Key=destination_key,
        )

        print(
            f"Disalin dari s3://{source_bucket}/{source_key} "
            f"ke s3://{DESTINATION_BUCKET}/{destination_key}"
        )

    return {
        "statusCode": 200,
        "processedRecords": len(event.get("Records", [])),
    }

Event S3 bisa dikirim lebih dari sekali

Desain konsumen secara idempotent, artinya memproses event yang sama dua kali tidak merusak data.

Pilihan pendekatan:

  • Gunakan bucket, key, version ID, atau ETag sebagai identitas pemrosesan.
  • Simpan status di DynamoDB dengan conditional write.
  • Pastikan output memakai key deterministik.
  • Jangan berasumsi event selalu datang dalam urutan sempurna.
  • Siapkan dead-letter queue untuk kegagalan berulang.

Step 19 — Pantau keamanan, biaya, dan pola penggunaan

S3 yang berjalan baik tetap perlu dipantau. Fokuskan pengamatan pada tiga area: keamanan, operasi, dan biaya.

Metrik dan catatan yang berguna

  • CloudTrail untuk aktivitas API.
  • S3 server access logging jika diperlukan.
  • CloudWatch request metrics.
  • S3 Storage Lens.
  • S3 Inventory.
  • AWS Config.
  • IAM Access Analyzer.
  • Cost Explorer dan AWS Budgets.

Buat anggaran biaya

Perkiraan S3 harus memasukkan:

TEXT
Total biaya =
  penyimpanan
  + request
  + retrieval
  + transfer data
  + replikasi
  + monitoring
  + KMS
  + layanan pendukung

Kesalahan umum adalah menghitung hanya:

TEXT
ukuran data × harga per GB

Padahal sistem gambar dengan volume baca besar mungkin lebih banyak membayar transfer data daripada penyimpanan.

Contoh perhitungan sederhana

Anggap sebuah aplikasi menyimpan:

  • 1 TB gambar.
  • 2 juta unggahan per bulan.
  • 50 juta pembacaan per bulan.
  • 3 TB transfer ke pengguna.
  • Replikasi tidak diaktifkan.

Perhitungan perlu memisahkan:

  • Harga penyimpanan 1 TB.
  • PUT untuk 2 juta upload.
  • GET untuk 50 juta pembacaan.
  • Transfer keluar 3 TB.
  • Biaya CloudFront jika dipakai.
  • Biaya invalidation atau fitur tambahan.
  • Pajak yang berlaku.

Gunakan AWS Pricing Calculator untuk model yang lebih terstruktur. Tetap bandingkan hasil kalkulator dengan tagihan aktual setelah sistem berjalan.

Step 20 — Uji pemulihan, bukan hanya proses upload

Cadangan belum terbukti berguna sampai proses pemulihannya berhasil diuji.

Buat prosedur uji:

  1. Pilih beberapa objek secara acak.
  2. Unduh dan verifikasi checksum.
  3. Pulihkan versi lama.
  4. Uji objek di storage class arsip.
  5. Catat waktu mulai dan selesai.
  6. Pastikan pengguna yang tepat dapat memulihkan data.
  7. Pastikan pengguna yang tidak berwenang tidak bisa melakukannya.
  8. Simulasikan kehilangan key atau penghapusan tidak sengaja.

Hitung dua metrik:

  • RPO atau Recovery Point Objective: seberapa banyak data yang boleh hilang.
  • RTO atau Recovery Time Objective: seberapa lama layanan boleh menunggu pemulihan.

Jika bisnis meminta pemulihan dalam lima menit, Deep Archive bukan pilihan yang tepat untuk satu-satunya salinan data tersebut.

Kesalahan umum Amazon S3 dan cara mengatasinya

AccessDenied

Contoh:

TEXT
An error occurred (AccessDenied) when calling the PutObject operation:
Access Denied

Periksa:

  • IAM policy pengguna atau role.
  • Bucket policy.
  • KMS key policy.
  • Service Control Policy di AWS Organizations.
  • Permissions boundary.
  • VPC endpoint policy.
  • Block Public Access.
  • Object Ownership.
  • ARN bucket dan objek.
  • Explicit deny.

Gunakan:

BASH
aws sts get-caller-identity

Kemudian pastikan identitas itulah yang diberi izin.

NoSuchBucket

TEXT
An error occurred (NoSuchBucket): The specified bucket does not exist

Penyebab:

  • Nama salah.
  • Bucket telah dihapus.
  • Variabel lingkungan kosong.
  • Akun yang dipakai berbeda.

Periksa:

BASH
echo "$BUCKET_NAME"
aws s3api head-bucket --bucket "$BUCKET_NAME"

NoSuchKey

S3 membedakan huruf besar dan kecil:

TEXT
Images/Logo.png

berbeda dari:

TEXT
images/logo.png

Cetak key lengkap ke log dan hindari normalisasi yang tidak konsisten.

PermanentRedirect

Biasanya request dikirim ke endpoint region yang salah.

Periksa region bucket:

BASH
aws s3api get-bucket-location --bucket "$BUCKET_NAME"

Pastikan client Boto3 memakai region yang cocok:

PYTHON
boto3.client("s3", region_name="ap-southeast-3")

RequestTimeTooSkewed

Jam perangkat terlalu jauh dari waktu sebenarnya.

Perbaikan:

  • Aktifkan sinkronisasi waktu.
  • Gunakan NTP.
  • Periksa zona waktu sistem.
  • Jangan mengubah parameter presigned URL.

Upload berhenti atau lambat

Periksa:

  • Kualitas jaringan.
  • Ukuran multipart chunk.
  • Tingkat concurrency.
  • CPU dan disk lokal.
  • VPN atau proxy.
  • Jarak ke region.
  • Packet loss.
  • Batas bandwidth kantor.

Jangan langsung menaikkan concurrency ke angka besar. Uji bertahap, misalnya 4, 8, lalu 16.

Biaya naik mendadak

Cari perubahan pada:

  • Transfer data keluar.
  • Jumlah GET, PUT, dan LIST.
  • Versi noncurrent.
  • Multipart upload yang belum selesai.
  • Replikasi.
  • KMS request.
  • Objek kecil dalam jumlah sangat besar.
  • Aktivitas bot.
  • Lifecycle transition.
  • Pemulihan Glacier.
  • Log yang tumbuh tanpa retensi.

Objek terhapus tetapi biaya tidak turun

Kemungkinan penyebab:

  • Versioning aktif dan versi lama masih ada.
  • Delete marker dibuat, tetapi data lama tetap tersimpan.
  • Penghapusan belum tercermin pada laporan biaya harian.
  • Multipart upload belum dibatalkan.
  • Ada replikasi atau salinan lain.

Lihat versi:

BASH
aws s3api list-object-versions \
  --bucket "$BUCKET_NAME"

Lihat multipart upload:

BASH
aws s3api list-multipart-uploads \
  --bucket "$BUCKET_NAME"

Tips optimasi Amazon S3 untuk aplikasi Indonesia

Gunakan region yang dekat dengan komputasi

Jika backend berada di AWS Jakarta, bucket di Jakarta sering menjadi titik awal yang masuk akal. Jangan memilih region hanya karena harga per GB terlihat sedikit lebih rendah tanpa menghitung transfer, latensi, dan kebutuhan operasional.

Pisahkan lingkungan

Gunakan bucket terpisah:

TEXT
acme-media-dev
acme-media-staging
acme-media-prod

Pemisahan ini membuat IAM policy, lifecycle, anggaran, dan proses penghapusan lebih aman.

Jangan masukkan data pribadi ke nama key

Hindari:

TEXT
uploads/andi-saputra-3173xxxxxxxxxxxx/ktp.jpg

Gunakan ID internal:

TEXT
uploads/customer-873/document-550e8400.pdf

Nama bucket dan key dapat muncul dalam log, metrik, serta alat operasional.

Gunakan key yang tidak mudah ditebak

Key acak bukan pengganti otorisasi, tetapi membantu menghindari tabrakan dan paparan pola data:

PYTHON
from uuid import uuid4

object_key = f"uploads/{uuid4()}.jpg"

Simpan key, bukan URL permanen

Di database, lebih aman menyimpan:

TEXT
uploads/customer-873/profile.jpg

daripada URL endpoint lengkap.

Dengan begitu, domain, CloudFront distribution, atau pola akses dapat diganti tanpa memperbarui seluruh record.

Terapkan tag biaya

Gunakan tag bucket seperti:

  • Environment=Production
  • Application=Commerce
  • Owner=Platform
  • CostCenter=ID-Online
  • DataClassification=Internal

Tag membantu alokasi biaya, tetapi aturan penamaan dan kepemilikannya harus konsisten.

Uji dengan data realistis

Pengujian 20 berkas kecil tidak cukup untuk mewakili:

  • Jutaan objek.
  • Video beberapa gigabyte.
  • Lonjakan upload.
  • Proses listing besar.
  • Pemulihan arsip.
  • Transfer antarkota dan antarnegara.

Buat pengujian yang mendekati pola produksi, lalu ukur biaya serta waktu respons.

Studi kasus: migrasi media toko daring ke Amazon S3

Background

Sebuah skenario toko daring Indonesia memiliki backend di Jakarta dan melayani pelanggan dari berbagai kota. Pada tahap awal, gambar produk disimpan di disk server aplikasi.

Arsitektur ini sederhana:

TEXT
Pengguna -> Server aplikasi -> Folder gambar lokal

Volume awal hanya 40 GB dengan sekitar 15.000 gambar. Setelah katalog berkembang dan penjual mulai mengunggah beberapa foto per produk, koleksi media tumbuh menjadi 1,8 TB.

Challenge/Problem

Tim menghadapi beberapa masalah:

  • Deployment baru berisiko mengganggu folder media.
  • Proses backup memerlukan waktu panjang.
  • Menambah server berarti menyinkronkan berkas.
  • Gambar dilayani langsung oleh backend.
  • Waktu respons meningkat saat kampanye promosi.
  • Berkas lama tidak memiliki aturan retensi.
  • Tidak ada pemisahan area upload dan aset terverifikasi.

Masalah utamanya bukan sekadar kekurangan ruang. Penyimpanan lokal membuat server aplikasi memikul tanggung jawab yang seharusnya dipisahkan.

Approach

Tim memilih pola berikut:

TEXT
Browser
   |
   | meminta izin upload
   v
API aplikasi
   |
   | membuat presigned POST
   v
Browser mengunggah langsung ke S3
   |
   v
S3 Event -> SQS -> Lambda pemeriksa gambar
   |
   v
Prefix aset terverifikasi
   |
   v
CloudFront -> Pelanggan

Keputusan utamanya:

  • Bucket tetap privat.
  • Upload dilakukan melalui presigned POST.
  • Ukuran berkas dibatasi.
  • Objek baru masuk ke prefix karantina.
  • Pemrosesan berjalan asinkron.
  • Gambar hasil optimasi memiliki nama berbasis hash.
  • CloudFront melayani konten.
  • Versioning aktif pada aset penting.
  • Lifecycle membersihkan upload gagal dan versi lama.

Implementation

Struktur key:

TEXT
quarantine/{seller_id}/{upload_id}/original.jpg
verified/{product_id}/{content_hash}/large.webp
verified/{product_id}/{content_hash}/thumbnail.webp
rejected/{seller_id}/{upload_id}/original.jpg

Database hanya menyimpan:

JSON
{
  "product_id": "PRD-10291",
  "image_key": "verified/PRD-10291/8f4c21a/large.webp",
  "thumbnail_key": "verified/PRD-10291/8f4c21a/thumbnail.webp",
  "status": "ready"
}

Bucket policy menolak koneksi tanpa TLS. IAM role pemroses hanya bisa membaca prefix karantina dan menulis ke prefix hasil.

Lifecycle yang dipakai:

  • Multipart upload yang tidak selesai dibatalkan setelah tujuh hari.
  • Objek yang ditolak dihapus setelah 30 hari.
  • Versi noncurrent dipindahkan setelah 30 hari.
  • Versi noncurrent dihapus setelah 180 hari.
  • Log akses dipindahkan ke kelas arsip sesuai retensi.

Results

Dalam simulasi beban dan proyeksi operasional, desain ini dapat menghasilkan perubahan seperti berikut:

Metrik Sebelum Sesudah Dampak
Data media pada disk aplikasi 1,8 TB Kurang dari 5 GB cache Server lebih mudah diganti
Lalu lintas gambar melalui backend 100% Kurang dari 5% Beban koneksi backend turun
Waktu deployment 28 menit 11 menit Tidak perlu menyertakan media
Pemulihan berkas terhapus Manual dari backup Mengambil versi objek Proses lebih cepat
Upload maksimum Bergantung timeout backend Langsung ke S3 Upload besar lebih stabil
Pemrosesan lonjakan Sinkron SQS sebagai buffer Kegagalan lebih terkontrol

Angka tersebut merupakan ilustrasi skenario, bukan jaminan hasil. Dampak nyata bergantung pada ukuran aset, cache hit ratio, jaringan, konfigurasi CDN, dan pola penggunaan.

Key Learnings

  • Memindahkan berkas ke S3 saja belum cukup. Jalur upload dan distribusi juga perlu didesain ulang.
  • Bucket privat dengan presigned URL lebih aman daripada menjadikan semua objek publik.
  • CloudFront mengurangi pekerjaan backend, tetapi cache key dan header tetap harus dirancang.
  • Event dapat terkirim lebih dari sekali, jadi pemroses harus idempotent.
  • Lifecycle menjaga biaya versi lama dan upload gagal.
  • Database sebaiknya menyimpan object key, bukan salinan file atau URL endpoint yang sulit diubah.

Penilaian Amazon S3 sebagai produk penyimpanan cloud

Fitur yang paling bernilai

Skalabilitas otomatis adalah nilai utama S3. Tim tidak perlu menghitung berapa disk yang harus dibeli atau dipasang bulan depan.

Ekosistem integrasi juga kuat. S3 bisa menjadi sumber data untuk analitik, machine learning, automasi event, distribusi konten, dan backup.

Kontrol lifecycle membuat data dapat berpindah ke kelas yang lebih murah tanpa pekerjaan manual per objek.

Model keamanan sangat rinci. Ini bagus untuk perusahaan, tetapi bisa terasa rumit jika IAM, bucket policy, KMS policy, dan organisasi AWS tidak dikelola dengan disiplin.

Kelebihan

  • Kapasitas praktis tidak perlu direncanakan secara manual.
  • Tersedia banyak storage class.
  • API dan SDK matang.
  • Cocok untuk arsitektur cloud-native.
  • Daya tahan data sangat tinggi.
  • Mendukung versioning, replication, Object Lock, dan lifecycle.
  • Integrasi dengan CDN dan layanan analitik sangat luas.
  • Dokumentasi resmi tersedia melalui panduan Amazon S3.

Kekurangan

  • Struktur biaya lebih rumit daripada sekadar harga per GB.
  • Kesalahan policy dapat menyebabkan akses gagal atau paparan data.
  • Transfer keluar dapat mahal pada workload tertentu.
  • Listing dan pengelolaan jutaan objek perlu desain yang baik.
  • Bukan pengganti database atau file system penuh.
  • Storage class arsip memerlukan perencanaan pemulihan.
  • Jutaan objek kecil dapat mengurangi efisiensi biaya.
  • Pemakaian KMS pada request besar perlu dihitung terpisah.

Siapa yang sebaiknya memilih Amazon S3?

S3 layak dipilih oleh:

  • Perusahaan yang sudah memakai AWS.
  • Tim aplikasi yang ingin memisahkan media dari server.
  • Organisasi dengan data backup dan arsip.
  • Tim data yang membangun data lake.
  • Aplikasi yang membutuhkan upload langsung dari browser.
  • Sistem dengan volume data yang berubah cepat.
  • Perusahaan di Indonesia yang menjalankan komputasi di region AWS terdekat.

Siapa yang perlu mempertimbangkan pilihan lain?

Pertimbangkan alternatif jika:

  • Aplikasi wajib memakai file locking POSIX.
  • Data hanya dipakai oleh satu server dan membutuhkan latensi block storage.
  • Biaya transfer keluar mendominasi anggaran.
  • Organisasi harus memakai infrastruktur lokal tertentu.
  • Aplikasi bergantung pada API penyedia lain.
  • Tim tidak siap mengelola IAM dan tata kelola cloud.

S3-compatible storage dari penyedia lain mungkin menarik untuk kebutuhan tertentu, tetapi kompatibilitas API tidak selalu berarti seluruh fitur, perilaku, performa, dan model konsistensinya identik.

Rekomendasi akhir berdasarkan skenario penggunaan

Skenario Rekomendasi Alasan
Foto produk aktif S3 Standard + CloudFront Akses sering dan distribusi luas
Dokumen dengan pola akses berubah Intelligent-Tiering Perpindahan tier otomatis
Backup bulanan Standard-IA atau Glacier Flexible Retrieval Akses jarang dan terencana
Arsip pajak jangka panjang Glacier Deep Archive Biaya penyimpanan rendah
Data sementara yang bisa dibuat ulang One Zone-IA Biaya lebih rendah dengan risiko satu AZ
Dataset analitik aktif S3 Standard atau S3 Tables sesuai kebutuhan Throughput dan integrasi analitik
Upload pengguna Bucket privat + presigned POST Akses sementara dan terkontrol
Situs dengan aset global S3 privat + CloudFront Cache, HTTPS, dan kontrol origin
Pemrosesan gambar S3 Event + SQS + Lambda Pemrosesan asinkron dan elastis
Data sensitif S3 + KMS + policy ketat + audit Kontrol kunci dan jejak aktivitas

Checklist produksi Amazon S3

Keamanan

  • Block Public Access aktif.
  • ACL dinonaktifkan jika tidak dibutuhkan.
  • IAM mengikuti prinsip least privilege.
  • Bucket policy menolak koneksi tanpa TLS.
  • KMS dipakai jika kebutuhan audit dan kontrol kunci mengharuskannya.
  • Tidak ada access key di source code.
  • Presigned URL memiliki masa berlaku singkat.
  • CORS hanya mengizinkan origin yang dibutuhkan.
  • Upload pengguna masuk ke area karantina.
  • Access Analyzer dan CloudTrail diperiksa.

Keandalan

  • Versioning aktif untuk data penting.
  • Replikasi dipertimbangkan berdasarkan RPO dan RTO.
  • Proses pemulihan sudah diuji.
  • Multipart upload yang mangkrak dibersihkan.
  • Konsumen event bersifat idempotent.
  • Retry memiliki batas dan exponential backoff.
  • Checksum digunakan untuk transfer penting.
  • Pemilik prosedur pemulihan sudah ditentukan.

Biaya

  • Storage class dipilih berdasarkan pola akses.
  • Lifecycle policy aktif.
  • Versi noncurrent memiliki masa retensi.
  • Biaya request dihitung.
  • Biaya retrieval dihitung.
  • Transfer keluar dihitung.
  • Penggunaan KMS dihitung.
  • Objek kecil dianalisis.
  • AWS Budgets dan peringatan biaya aktif.
  • Tag alokasi biaya diterapkan.

Operasional

  • Penamaan bucket konsisten.
  • Lingkungan development, staging, dan production dipisahkan.
  • Region bucket didokumentasikan.
  • Object key tidak memuat data pribadi.
  • Database menyimpan key, bukan URL yang kaku.
  • Policy disimpan dalam version control.
  • Perubahan infrastruktur melalui proses review.
  • Dashboard dan alarm telah dibuat.
  • Retensi data disetujui pemilik bisnis.
  • Penghapusan data memiliki prosedur verifikasi.

Kesimpulan

Amazon S3 bukan sekadar tempat menyimpan objek, melainkan fondasi penyimpanan cloud yang perlu dirancang sesuai pola akses, tingkat sensitivitas data, target pemulihan, dan anggaran. Storage class yang tepat, arsitektur akses privat, serta integrasi dengan layanan distribusi dan pemrosesan dapat meningkatkan performa tanpa mengorbankan keamanan.

Implementasi yang matang juga membutuhkan pengendalian operasional berkelanjutan. Versioning, lifecycle policy, enkripsi, audit, pemantauan biaya, dan pengujian pemulihan harus diperlakukan sebagai bagian dari desain sejak awal. Gunakan dokumentasi resmi Amazon S3 sebagai rujukan ketika memvalidasi konfigurasi dan keputusan arsitektur.

Mulailah dari kebutuhan nyata, terapkan checklist produksi secara bertahap, lalu ukur hasilnya. Amazon S3 memberikan fleksibilitas besar, tetapi nilai terbaiknya baru terasa ketika setiap keputusan penyimpanan dibuat dengan sadar, diuji, dan terus dievaluasi.


Referensi

AWS. (2026). Cloud Object Storage: Amazon S3.

AWS. (2026). Amazon S3 Pricing.

GeeksforGeeks. (2026). AWS Simple Storage Service (AWS S3).

Wikipedia. (2026). Amazon S3.

Amazon S3. (2026). Welcome to Amazon S3.

DataCamp. (2026). What Is Amazon S3? Your Guide to Scalable Cloud Storage.

Amazon S3. (2026). Amazon S3 Explorer (v2 Alpha).

Computer Weekly. (2026). Storage Technology Explained: What Is S3 and What Is It Good For?

GeeksforGeeks. (2026). Amazon S3 Storage Classes.

Cloudtech. (2026). What Is Amazon S3, and Why Should It Be Part of a Data Strategy for SMBs?

Komentar (0)

Belum ada komentar. Jadilah yang pertama berbagi pendapat!

Tinggalkan komentar