Memulihkan File S3 yang Terhapus: Panduan Lengkap dengan Versioning

Kamu baru saja menjalankan perintah aws s3 rm atau menghapus objek lewat konsol, lalu sadar itu file yang salah — skenario ini lebih sering terjadi di production daripada yang mau diakui siapa pun. Jika S3 Versioning sudah aktif di bucket tersebut, file itu belum benar-benar hilang; yang terjadi adalah AWS menambahkan sebuah delete marker di atas versi terakhir objek. Artikel ini menjelaskan cara menemukan dan memulihkan versi sebelumnya dari objek S3 yang terhapus menggunakan AWS CLI dan konsol.

TL;DR — Pemulihan File S3 dengan Versioning

LangkahAksiPerintah Utama
1Konfirmasi Versioning aktifaws s3api get-bucket-versioning
2Temukan delete markeraws s3api list-object-versions
3Identifikasi Version ID yang ingin dipulihkanaws s3api list-object-versions --query
4Hapus delete markeraws s3api delete-object --version-id <marker-id>
5Verifikasi objek kembali tersediaaws s3api head-object

Bagaimana S3 Versioning Bekerja Saat File Dihapus

Sebelum masuk ke langkah pemulihan, penting untuk memahami apa yang sebenarnya terjadi ketika kamu menghapus objek di bucket yang sudah mengaktifkan Versioning. AWS tidak menghapus data secara permanen — melainkan menyisipkan sebuah objek khusus bernama delete marker sebagai versi terbaru dari key tersebut.

Delete marker tidak memiliki data, tidak bisa diunduh, dan tidak dikenakan biaya storage seperti objek biasa. Namun keberadaannya membuat objek 'tidak terlihat' di operasi GET dan LIST standar — seolah-olah file sudah hilang. Versi-versi lama tetap ada di storage dan bisa dipulihkan kapan saja selama delete marker belum dihapus secara permanen.

Ada satu hal yang sering menjebak: jika kamu menghapus objek dengan menyertakan Version ID tertentu, itu adalah penghapusan permanen — tidak ada delete marker, data langsung hilang. Mekanisme delete marker hanya berlaku untuk penghapusan tanpa Version ID.

graph TD A["Objek Ada di S3
Versioning Aktif"] --> B["DELETE tanpa Version ID"] A --> C["DELETE dengan Version ID"] B --> D["Delete Marker Dibuat
IsLatest = true"] D --> E["GET Request Normal"] E --> F["HTTP 404 Not Found
Versi lama masih ada"] F --> G["Hapus Delete Marker
delete-object --version-id marker-id"] G --> H["Versi Lama Kembali Aktif
IsLatest = true"] C --> I["Penghapusan Permanen
Data hilang selamanya"]
  1. Operasi DELETE tanpa Version ID — AWS menyisipkan delete marker sebagai versi terbaru. Versi lama tetap ada.
  2. GET request setelah delete marker — AWS mengembalikan HTTP 404 karena versi terbaru adalah delete marker, bukan data.
  3. Hapus delete marker — Versi sebelumnya kembali menjadi versi terbaru dan bisa diakses normal.
  4. DELETE dengan Version ID spesifik — Penghapusan permanen, tidak bisa dipulihkan lewat mekanisme ini.

Prasyarat: Verifikasi S3 Versioning Aktif di Bucket

Langkah pertama bukan langsung mencari file — melainkan memastikan Versioning memang sudah aktif sebelum kejadian penghapusan. Jika Versioning baru diaktifkan setelah file terhapus, versi lama tidak akan ada.

aws s3api get-bucket-versioning \
  --bucket nama-bucket-kamu \
  --region us-east-1

Output yang diharapkan:

{
    "Status": "Enabled"
}

Jika output kosong ({}) atau statusnya Suspended, versi historis kemungkinan besar tidak tersedia untuk objek yang dihapus sebelum Versioning diaktifkan.

Memulihkan File S3 yang Terhapus: Langkah demi Langkah

Langkah 1 — Temukan Delete Marker dan Daftar Semua Versi Objek

Gunakan list-object-versions untuk melihat semua versi dan delete marker dari sebuah key. Ini adalah titik awal diagnosis — kamu perlu tahu Version ID dari delete marker dan Version ID dari versi data yang ingin dipulihkan.

aws s3api list-object-versions \
  --bucket nama-bucket-kamu \
  --prefix path/ke/file-kamu.txt \
  --region us-east-1

Output akan berisi dua bagian: Versions (versi data aktual) dan DeleteMarkers. Contoh output yang relevan:

🔽 Klik untuk melihat contoh output list-object-versions
{
    "Versions": [
        {
            "ETag": "\"d41d8cd98f00b204e9800998ecf8427e\"",
            "Size": 1024,
            "StorageClass": "STANDARD",
            "Key": "path/ke/file-kamu.txt",
            "VersionId": "abc123XYZversiLama",
            "IsLatest": false,
            "LastModified": "2024-01-15T08:30:00.000Z"
        }
    ],
    "DeleteMarkers": [
        {
            "Owner": {
                "DisplayName": "akun-kamu",
                "ID": "abc123"
            },
            "Key": "path/ke/file-kamu.txt",
            "VersionId": "xyz789DELETEmarker",
            "IsLatest": true,
            "LastModified": "2024-01-16T10:00:00.000Z"
        }
    ]
}

Catat dua nilai penting: VersionId dari delete marker (di bagian DeleteMarkers) dan VersionId dari versi data yang ingin kamu kembalikan (di bagian Versions).

Langkah 2 — Filter dengan Query untuk Bucket Besar

Jika bucket berisi ribuan objek, output mentah dari langkah sebelumnya bisa sangat panjang. Gunakan --query untuk langsung mengekstrak informasi yang dibutuhkan — ini menghemat waktu dan mengurangi risiko salah baca Version ID.

aws s3api list-object-versions \
  --bucket nama-bucket-kamu \
  --prefix path/ke/file-kamu.txt \
  --region us-east-1 \
  --query 'DeleteMarkers[?IsLatest==`true`].{Key:Key,VersionId:VersionId}'
aws s3api list-object-versions \
  --bucket nama-bucket-kamu \
  --prefix path/ke/file-kamu.txt \
  --region us-east-1 \
  --query 'Versions[?IsLatest==`false`].{Key:Key,VersionId:VersionId,LastModified:LastModified}'

Langkah 3 — Hapus Delete Marker untuk Memulihkan Objek

Ini adalah inti dari proses pemulihan. Menghapus delete marker — dengan menyertakan Version ID-nya secara eksplisit — membuat versi data sebelumnya kembali menjadi versi terbaru yang aktif. Tanpa --version-id, kamu justru akan membuat delete marker baru di atas delete marker lama.

aws s3api delete-object \
  --bucket nama-bucket-kamu \
  --key path/ke/file-kamu.txt \
  --version-id xyz789DELETEmarker \
  --region us-east-1

Output sukses akan mengembalikan DeleteMarker: true dan Version ID yang baru saja dihapus — konfirmasi bahwa delete marker sudah diangkat.

Analogi yang tepat: delete marker itu seperti sticky note 'DIHAPUS' yang ditempel di atas dokumen asli di lemari arsip. Dokumen aslinya tidak kemana-mana — kamu cukup cabut sticky note-nya, dan dokumen kembali terlihat.

Langkah 4 — Verifikasi Objek Kembali Tersedia

Setelah delete marker dihapus, konfirmasi bahwa objek bisa diakses kembali. head-object lebih efisien daripada get-object untuk verifikasi karena tidak mengunduh data aktual — cukup mengecek metadata dan memastikan tidak ada HTTP 404.

aws s3api head-object \
  --bucket nama-bucket-kamu \
  --key path/ke/file-kamu.txt \
  --region us-east-1

Jika perintah mengembalikan metadata objek (ukuran, ETag, LastModified) tanpa error, pemulihan berhasil. Jika masih muncul error 404 Not Found, kembali ke Langkah 1 dan periksa apakah masih ada delete marker lain.

Skenario Alternatif: Memulihkan Versi Spesifik (Bukan Versi Terbaru)

Kadang yang dibutuhkan bukan sekadar 'kembalikan file yang terhapus', tapi 'kembalikan file ke kondisi tiga hari lalu'. Dalam kasus ini, kamu perlu menyalin versi spesifik ke atas versi terbaru menggunakan copy-object dengan parameter --copy-source-version-id.

aws s3api copy-object \
  --bucket nama-bucket-kamu \
  --copy-source nama-bucket-kamu/path/ke/file-kamu.txt?versionId=abc123XYZversiLama \
  --key path/ke/file-kamu.txt \
  --region us-east-1

Operasi ini membuat versi baru dari objek dengan konten dari versi lama yang ditentukan. Versi-versi sebelumnya tetap terjaga — tidak ada data yang dihapus dalam proses ini.

graph TD START["File Terhapus
Perlu Dipulihkan"] --> Q{"Pulihkan ke versi
mana?"} Q --> |"Versi terakhir
sebelum dihapus"| L1["1. list-object-versions
Temukan delete marker"] Q --> |"Versi spesifik
di masa lalu"| R1["1. list-object-versions
Temukan Version ID target"] L1 --> L2["2. delete-object
--version-id marker-id"] R1 --> R2["2. copy-object
--copy-source-version-id target-id"] L2 --> V["3. head-object
Verifikasi aksesibilitas"] R2 --> V V --> |"HTTP 200 OK"| DONE["Pemulihan Berhasil"] V --> |"HTTP 404"| RETRY["Periksa delete marker lain"]
  1. Jalur kiri (Pulihkan ke versi terbaru sebelum dihapus) — Cukup hapus delete marker. Versi data terakhir otomatis menjadi aktif kembali.
  2. Jalur kanan (Pulihkan ke versi spesifik di masa lalu) — Gunakan copy-object dengan --copy-source-version-id untuk membuat versi baru dari konten lama.
  3. Kedua jalur — Diakhiri dengan verifikasi menggunakan head-object.

Pengalaman Nyata: Diagnosis yang Salah Arah

Ini pola yang sering terjadi: engineer menjalankan list-object-versions, melihat Version ID di bagian Versions, lalu langsung mencoba get-object --version-id untuk mengunduh file tersebut — dan berhasil. Mereka pikir masalah selesai.

Tapi ketika aplikasi atau user lain mencoba mengakses file lewat URL normal atau SDK tanpa Version ID, masih dapat 404. Penyebabnya: delete marker belum dihapus. get-object --version-id memang bisa mengakses versi lama secara langsung, tapi itu bypass delete marker — bukan menghapusnya.

Akses normal (tanpa Version ID) selalu mengarah ke versi terbaru, yang masih berupa delete marker. Solusi yang benar tetap sama: hapus delete marker menggunakan delete-object --version-id <marker-id>. Mengunduh file dengan Version ID eksplisit hanya berguna untuk memverifikasi konten versi lama, bukan untuk memulihkan aksesibilitas objek.

IAM: Permission yang Dibutuhkan untuk Operasi Pemulihan

Operasi pemulihan ini membutuhkan beberapa permission yang berbeda dari operasi S3 biasa. Khususnya, menghapus delete marker memerlukan s3:DeleteObjectVersion — permission yang sering tidak disertakan dalam policy standar read/write.

🔽 Klik untuk melihat contoh IAM Policy pemulihan S3
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "S3VersioningRecovery",
      "Effect": "Allow",
      "Action": [
        "s3:GetObjectVersion",
        "s3:ListBucketVersions",
        "s3:DeleteObjectVersion",
        "s3:GetBucketVersioning",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::nama-bucket-kamu",
        "arn:aws:s3:::nama-bucket-kamu/*"
      ]
    }
  ]
}

Perhatikan bahwa s3:ListBucketVersions diterapkan pada resource bucket (tanpa /*), sedangkan s3:GetObjectVersion dan s3:DeleteObjectVersion diterapkan pada resource objek (dengan /*). Kesalahan penempatan resource ini adalah penyebab umum permission denied yang membingungkan.

Memulihkan File S3 yang Terhapus Lewat AWS Console

Untuk pengguna yang lebih nyaman dengan antarmuka visual, AWS Console menyediakan cara yang lebih intuitif untuk proses yang sama.

  1. Buka S3 Console → pilih bucket → navigasi ke lokasi objek yang terhapus.
  2. Klik tombol 'Show versions' di bagian atas daftar objek. Kamu akan melihat semua versi termasuk delete marker (ditandai dengan label 'Delete marker').
  3. Pilih delete marker yang ingin dihapus (centang checkbox di sebelah kirinya).
  4. Klik 'Delete' → konfirmasi penghapusan. Ini menghapus delete marker, bukan data.
  5. Matikan kembali toggle 'Show versions' — objek seharusnya sudah muncul kembali di daftar normal.

Wrap-Up: Memulihkan File S3 yang Terhapus dan Langkah Selanjutnya

Memulihkan file S3 yang terhapus dengan Versioning aktif pada dasarnya adalah operasi dua langkah: temukan Version ID delete marker, lalu hapus delete marker tersebut. Kompleksitas muncul ketika bucket besar, ada banyak versi, atau ketika permission tidak dikonfigurasi dengan benar.

Untuk mencegah kejadian serupa di masa depan, pertimbangkan langkah-langkah berikut:

  • Aktifkan S3 Object Lock jika objek tidak boleh dihapus sama sekali dalam periode tertentu.
  • Konfigurasi S3 Lifecycle Rules untuk mengelola retensi versi lama secara otomatis dan menghindari biaya storage yang tidak terkontrol.
  • Gunakan S3 Replication ke bucket di region berbeda sebagai lapisan perlindungan tambahan.
  • Dokumentasi resmi: AWS S3 Versioning Documentation

Glosarium

IstilahPenjelasan
Delete MarkerObjek placeholder tanpa data yang disisipkan S3 saat objek dihapus di bucket dengan Versioning aktif. Membuat objek tidak terlihat di operasi standar.
Version IDIdentifier unik yang ditetapkan S3 untuk setiap versi objek, termasuk delete marker. Diperlukan untuk operasi yang menarget versi spesifik.
S3 VersioningFitur bucket S3 yang menyimpan semua versi objek, termasuk versi sebelum penghapusan atau penimpaan.
IsLatestFlag boolean dalam output list-object-versions yang menandai apakah sebuah versi adalah versi terbaru dari key tersebut.
Permanent DeletePenghapusan objek dengan menyertakan Version ID secara eksplisit. Tidak menghasilkan delete marker dan tidak bisa dipulihkan lewat mekanisme Versioning.

Komentar

Postingan populer dari blog ini

EC2 Tidak Bisa Akses Internet di Custom VPC: Cara Pasang Internet Gateway dan Update Route Table