Cloud Computing
Panduan Lengkap Amazon S3 : Fitur dan Cara Pakai
Daftar isi
- Masalah penyimpanan yang diselesaikan Amazon S3
- Cara kerja Amazon S3 dalam bahasa sederhana
- Kelebihan dan keterbatasan Amazon S3
- Kelebihan utama
- Keterbatasan yang perlu diperhatikan
- Siapa yang paling cocok memakai S3?
- Perbandingan Amazon S3 dengan penyimpanan file, block, dan database
- Getting Started: prasyarat sebelum memakai Amazon S3
- Step 1 — Pilih Region AWS dan strategi penempatan data
- Cara menentukan region
- Kesalahan yang sering terjadi
- Step 2 — Konfigurasikan kredensial AWS dengan aman
- Gunakan named profile untuk beberapa lingkungan
- Praktik aman untuk produksi
- Kebijakan IAM minimum untuk tutorial
- Step 3 — Buat bucket Amazon S3
- Catatan khusus us-east-1
- Error: BucketAlreadyExists
- Error: IllegalLocationConstraintException
- Step 4 — Pastikan bucket tetap privat
- Step 5 — Unggah dan unduh objek lewat AWS CLI
- Mengapa struktur key perlu dirancang?
- Unggah seluruh direktori
- Sinkronkan direktori
- Step 6 — Pahami metadata, content type, dan cache control
- Kapan memakai cache satu tahun?
- Tambahkan metadata khusus
- Step 7 — Akses Amazon S3 memakai Python dan Boto3
- Mengunggah data langsung dari memori
- Membaca objek dari S3
- Unduh objek ke berkas lokal
- Menampilkan objek berdasarkan prefix
- Step 8 — Buat presigned URL untuk akses sementara
- Presigned URL untuk unduhan
- Mengapa presigned URL penting?
- Presigned URL untuk unggahan
- Error: SignatureDoesNotMatch
- Batasi ukuran unggahan dengan presigned POST
- Step 9 — Atur CORS untuk unggahan dari browser
- Jangan memakai wildcard tanpa alasan
- Error CORS di browser
- Step 10 — Aktifkan versioning untuk melindungi objek
- Versioning bukan backup lengkap
- Biaya versioning
- Step 11 — Pilih storage class Amazon S3 yang tepat
- Perbandingan storage class
- Rekomendasi berdasarkan penggunaan
- Jebakan objek kecil
- Step 12 — Terapkan lifecycle policy untuk mengendalikan biaya
- Mengapa setiap bagian penting?
- Jangan menyalin lifecycle tanpa memahami retensi
- Step 13 — Kelola unggahan berkas besar dengan multipart upload
- Konfigurasi multipart di Python
- Step 14 — Tambahkan retry dan penanganan error yang layak
- Jangan mencoba ulang semua error
- Step 15 — Terapkan enkripsi sesuai kebutuhan
- Enkripsi SSE-S3
- Enkripsi SSE-KMS
- SSE-S3 versus SSE-KMS
- Error: KMS.AccessDeniedException
- Step 16 — Buat bucket policy yang membatasi koneksi tidak aman
- Step 17 — Distribusikan konten dengan CloudFront, bukan bucket publik
- Step 18 — Hubungkan S3 dengan event-driven processing
- Contoh fungsi Lambda Python
- Event S3 bisa dikirim lebih dari sekali
- Step 19 — Pantau keamanan, biaya, dan pola penggunaan
- Metrik dan catatan yang berguna
- Buat anggaran biaya
- Contoh perhitungan sederhana
- Step 20 — Uji pemulihan, bukan hanya proses upload
- Kesalahan umum Amazon S3 dan cara mengatasinya
- AccessDenied
- NoSuchBucket
- NoSuchKey
- PermanentRedirect
- RequestTimeTooSkewed
- Upload berhenti atau lambat
- Biaya naik mendadak
- Objek terhapus tetapi biaya tidak turun
- Tips optimasi Amazon S3 untuk aplikasi Indonesia
- Gunakan region yang dekat dengan komputasi
- Pisahkan lingkungan
- Jangan masukkan data pribadi ke nama key
- Gunakan key yang tidak mudah ditebak
- Simpan key, bukan URL permanen
- Terapkan tag biaya
- Uji dengan data realistis
- Studi kasus: migrasi media toko daring ke Amazon S3
- Background
- Challenge/Problem
- Approach
- Implementation
- Results
- Key Learnings
- Penilaian Amazon S3 sebagai produk penyimpanan cloud
- Fitur yang paling bernilai
- Kelebihan
- Kekurangan
- Siapa yang sebaiknya memilih Amazon S3?
- Siapa yang perlu mempertimbangkan pilihan lain?
- Rekomendasi akhir berdasarkan skenario penggunaan
- Checklist produksi Amazon S3
- Keamanan
- Keandalan
- Biaya
- Operasional
- Kesimpulan
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:
s3://demo-toko-id/produk/2026/sepatu-hitam.jpg
Bagian-bagiannya adalah:
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:
- Akun AWS aktif.
- Pengguna atau role IAM dengan izin yang sesuai.
- AWS CLI versi 2.
- Python 3.10 atau yang lebih baru untuk contoh program.
- Pustaka
boto3. - Terminal seperti PowerShell, Command Prompt, Terminal macOS, atau shell Linux.
- Nama bucket yang unik.
- Region AWS yang akan dipakai.
Periksa instalasi AWS CLI:
aws --version
Contoh keluaran:
aws-cli/2.27.18 Python/3.13.3 Linux/6.8.0 exe/x86_64
Periksa Python:
Baca juga Tencent Cloud Free Tier: 30+ Produk Gratis
python --version
Contoh keluaran:
Python 3.12.4
Instal boto3:
python -m pip install boto3
Contoh keluaran:
Successfully installed boto3-1.38.0 botocore-1.38.0
Jika bekerja dalam proyek, gunakan virtual environment supaya dependensi tidak bercampur dengan proyek lain:
python -m venv .venv
Aktifkan di Linux atau macOS:
source .venv/bin/activate
Aktifkan di Windows PowerShell:
.venv\Scripts\Activate.ps1
Lalu pasang boto3:
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-3untuk Asia Pacific Jakarta.ap-southeast-1untuk 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:
aws configure get region
Atur region default:
aws configure set region ap-southeast-3
Periksa kembali:
aws configure list
Contoh keluaran:
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:
-
Lokasi pengguna dan aplikasi
Letakkan data dekat dengan komputasi yang paling sering mengaksesnya. -
Kebutuhan residensi data
Beberapa organisasi memiliki aturan internal atau kontraktual soal lokasi penyimpanan. -
Ketersediaan layanan
Tidak semua fitur baru langsung tersedia di semua region. -
Biaya
Harga penyimpanan dan transfer dapat berbeda antarregion. -
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:
aws configure
Masukkan nilai yang diminta:
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:
aws sts get-caller-identity
Contoh keluaran:
{
"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:
aws configure --profile s3-lab
Pakai profil tersebut:
aws sts get-caller-identity --profile s3-lab
Atau melalui variabel lingkungan:
export AWS_PROFILE=s3-lab
Di 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:
{
"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:
acme-media-prod-id-123456
Hindari memasukkan:
- Nama pengguna pribadi.
- Alamat email.
- Data pelanggan.
- Informasi rahasia.
- Nama yang terlalu umum seperti
imagesataubackup.
Simpan nama bucket dalam variabel:
BUCKET_NAME="acme-s3-tutorial-id-123456"
AWS_REGION="ap-southeast-3"
Buat bucket di region Jakarta:
aws s3api create-bucket \
--bucket "$BUCKET_NAME" \
--region "$AWS_REGION" \
--create-bucket-configuration LocationConstraint="$AWS_REGION"
Contoh keluaran:
{
"Location": "http://acme-s3-tutorial-id-123456.s3.amazonaws.com/"
}
Periksa bucket:
aws s3api head-bucket --bucket "$BUCKET_NAME"
Jika berhasil, perintah biasanya tidak menampilkan keluaran dan mengembalikan exit code 0.
Lihat daftar bucket:
aws s3 ls
Contoh keluaran:
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:
aws s3api create-bucket \
--bucket "$BUCKET_NAME" \
--region us-east-1
Error: BucketAlreadyExists
Contoh:
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:
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:
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:
aws s3api put-public-access-block \
--bucket "$BUCKET_NAME" \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
Periksa hasilnya:
aws s3api get-public-access-block --bucket "$BUCKET_NAME"
Keluaran yang diharapkan:
{
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}
}
Aktifkan Bucket Owner Enforced agar ACL dinonaktifkan:
aws s3api put-bucket-ownership-controls \
--bucket "$BUCKET_NAME" \
--ownership-controls \
'Rules=[{ObjectOwnership=BucketOwnerEnforced}]'
Periksa konfigurasi:
aws s3api get-bucket-ownership-controls --bucket "$BUCKET_NAME"
Keluaran:
{
"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:
mkdir -p data
echo "Laporan penjualan Juli 2026" > data/laporan.txt
Unggah ke S3:
aws s3 cp data/laporan.txt \
"s3://$BUCKET_NAME/laporan/2026/07/laporan.txt"
Keluaran:
upload: data/laporan.txt to s3://acme-s3-tutorial-id-123456/laporan/2026/07/laporan.txt
Lihat daftar objek:
aws s3 ls "s3://$BUCKET_NAME/laporan/2026/07/"
Keluaran:
2026-07-11 15:25:03 30 laporan.txt
Unduh kembali:
mkdir -p hasil
aws s3 cp \
"s3://$BUCKET_NAME/laporan/2026/07/laporan.txt" \
hasil/laporan.txt
Keluaran:
download: s3://acme-s3-tutorial-id-123456/laporan/2026/07/laporan.txt to hasil/laporan.txt
Periksa isi:
cat hasil/laporan.txt
Keluaran:
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:
uploads/{customer_id}/{year}/{month}/{uuid}-{filename}
Contoh konkret:
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
aws s3 cp ./assets "s3://$BUCKET_NAME/assets/" --recursive
Sinkronkan direktori
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:
aws s3 sync ./assets "s3://$BUCKET_NAME/assets/" --delete
Gunakan --dryrun lebih dulu:
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:
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:
aws s3api head-object \
--bucket "$BUCKET_NAME" \
--key "assets/logo.png"
Contoh keluaran:
{
"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:
logo.8f4c21a.png
Jangan memakai cache sangat panjang untuk nama yang isinya sering ditimpa:
logo.png
Jika isi logo.png diganti tetapi browser menyimpan versi lama selama setahun, pengguna bisa terus melihat gambar lama.
Tambahkan metadata khusus
aws s3 cp data/laporan.txt \
"s3://$BUCKET_NAME/laporan/laporan-metadata.txt" \
--metadata "department=finance,classification=internal"
Periksa:
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:
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:
python s3_tutorial.py
Keluaran:
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
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:
"6f5902ac237024bdd0c176cb93063dc4"
Jangan menganggap ETag selalu sama dengan MD5. Pada multipart upload dan beberapa konfigurasi enkripsi, bentuk ETag dapat berbeda.
Membaca objek dari S3
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:
{'order_id': 'ORD-2026-0001', 'city': 'Jakarta', 'total': 275000}
Unduh objek ke berkas lokal
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:
Unduhan selesai
Menampilkan objek berdasarkan prefix
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:
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:
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:
python presigned_download.py
Keluaran akan menyerupai:
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:
- Pengguna meminta berkas.
- Server mengunduh berkas dari S3.
- 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
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:
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-Typesaat 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:
"ContentType": "image/jpeg"
maka request harus mengirim:
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:
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:
Aplikasi: https://app.example.id
Bucket: https://bucket-name.s3.ap-southeast-3.amazonaws.com
Buat cors.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:
aws s3api put-bucket-cors \
--bucket "$BUCKET_NAME" \
--cors-configuration file://cors.json
Periksa:
aws s3api get-bucket-cors --bucket "$BUCKET_NAME"
Jangan memakai wildcard tanpa alasan
Konfigurasi berikut terlalu longgar untuk banyak sistem:
{
"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:
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
OPTIONSharus 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:
aws s3api put-bucket-versioning \
--bucket "$BUCKET_NAME" \
--versioning-configuration Status=Enabled
Periksa:
aws s3api get-bucket-versioning --bucket "$BUCKET_NAME"
Keluaran:
{
"Status": "Enabled"
}
Unggah versi pertama:
echo "Versi pertama" > data/kontrak.txt
aws s3 cp data/kontrak.txt \
"s3://$BUCKET_NAME/dokumen/kontrak.txt"
Unggah versi kedua:
echo "Versi kedua" > data/kontrak.txt
aws s3 cp data/kontrak.txt \
"s3://$BUCKET_NAME/dokumen/kontrak.txt"
Lihat semua versi:
aws s3api list-object-versions \
--bucket "$BUCKET_NAME" \
--prefix "dokumen/kontrak.txt"
Contoh keluaran ringkas:
{
"Versions": [
{
"Key": "dokumen/kontrak.txt",
"VersionId": "new-version-id",
"IsLatest": true
},
{
"Key": "dokumen/kontrak.txt",
"VersionId": "old-version-id",
"IsLatest": false
}
]
}
Unduh versi tertentu:
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:
{
"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:
aws s3api put-bucket-lifecycle-configuration \
--bucket "$BUCKET_NAME" \
--lifecycle-configuration file://lifecycle.json
Periksa:
aws s3api get-bucket-lifecycle-configuration \
--bucket "$BUCKET_NAME"
Mengapa setiap bagian penting?
Filter. Prefixmemastikan aturan hanya berlaku padalogs/.Transitionsmemindahkan objek ke kelas yang lebih murah.Expirationmenghapus data setelah tujuh tahun.NoncurrentVersionTransitionsmengurangi biaya versi lama.NoncurrentVersionExpirationmencegah versi lama menumpuk selamanya.AbortIncompleteMultipartUploadmembersihkan 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:
aws s3 cp video-besar.mp4 \
"s3://$BUCKET_NAME/video/video-besar.mp4"
Untuk melihat multipart upload yang belum selesai:
aws s3api list-multipart-uploads \
--bucket "$BUCKET_NAME"
Contoh keluaran:
{
"Uploads": [
{
"UploadId": "example-upload-id",
"Key": "video/video-besar.mp4"
}
]
}
Batalkan upload tertentu:
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
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:
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:
AccessDeniedNoSuchBucketInvalidAccessKeyIdSignatureDoesNotMatchInvalidArgument
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:
aws s3 cp data/laporan.txt \
"s3://$BUCKET_NAME/secure/laporan.txt" \
--sse AES256
Enkripsi SSE-KMS
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:
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:
- Identitas memiliki izin S3.
- Identitas juga diizinkan memakai KMS key.
Contoh izin KMS yang mungkin diperlukan:
{
"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:
{
"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:
aws s3api put-bucket-policy \
--bucket "$BUCKET_NAME" \
--policy file://bucket-policy.json
Periksa:
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:
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:
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
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:
Total biaya =
penyimpanan
+ request
+ retrieval
+ transfer data
+ replikasi
+ monitoring
+ KMS
+ layanan pendukung
Kesalahan umum adalah menghitung hanya:
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:
- Pilih beberapa objek secara acak.
- Unduh dan verifikasi checksum.
- Pulihkan versi lama.
- Uji objek di storage class arsip.
- Catat waktu mulai dan selesai.
- Pastikan pengguna yang tepat dapat memulihkan data.
- Pastikan pengguna yang tidak berwenang tidak bisa melakukannya.
- 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:
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:
aws sts get-caller-identity
Kemudian pastikan identitas itulah yang diberi izin.
NoSuchBucket
An error occurred (NoSuchBucket): The specified bucket does not exist
Penyebab:
- Nama salah.
- Bucket telah dihapus.
- Variabel lingkungan kosong.
- Akun yang dipakai berbeda.
Periksa:
echo "$BUCKET_NAME"
aws s3api head-bucket --bucket "$BUCKET_NAME"
NoSuchKey
S3 membedakan huruf besar dan kecil:
Images/Logo.png
berbeda dari:
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:
aws s3api get-bucket-location --bucket "$BUCKET_NAME"
Pastikan client Boto3 memakai region yang cocok:
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:
aws s3api list-object-versions \
--bucket "$BUCKET_NAME"
Lihat multipart upload:
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:
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:
uploads/andi-saputra-3173xxxxxxxxxxxx/ktp.jpg
Gunakan ID internal:
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:
from uuid import uuid4
object_key = f"uploads/{uuid4()}.jpg"
Simpan key, bukan URL permanen
Di database, lebih aman menyimpan:
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=ProductionApplication=CommerceOwner=PlatformCostCenter=ID-OnlineDataClassification=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:
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:
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:
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:
{
"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