Blue-green deployment adalah strategi rilis di mana dua environment identik disiapkan: satu melayani trafik produksi saat ini, satu lagi menjadi kandidat rilis berikutnya. Tujuan utamanya sederhana: cutover harus aman, rollback harus cepat, dan keputusan pengalihan trafik harus berdasarkan sinyal sistem yang jelas, bukan asumsi.

Untuk aplikasi web/backend, masalah terbesar saat deployment biasanya bukan sekadar proses build atau start container, melainkan hal-hal seperti koneksi database yang putus, migration yang tidak kompatibel saat rollback, health check yang terlalu dangkal, atau anomali performa yang baru muncul setelah trafik penuh masuk. Karena itu, panduan ini fokus pada urutan eksekusi yang praktis, kriteria kelulusan sebelum cutover, serta runbook rollback yang bisa dijalankan cepat tanpa bergantung pada vendor tertentu.

Apa itu Blue-Green Deployment dan kapan cocok digunakan

Dalam pola blue-green, misalkan environment Blue sedang aktif melayani produksi. Versi baru dirilis ke environment Green terlebih dahulu. Green diuji dalam kondisi mirip produksi, lalu trafik dialihkan dari Blue ke Green ketika semua pemeriksaan lolos.

Pendekatan ini cocok jika Anda membutuhkan:

  • Downtime minimal saat rilis.
  • Rollback cepat dengan mengalihkan trafik kembali ke environment lama.
  • Isolasi risiko karena versi baru tidak langsung menyentuh seluruh trafik.
  • Verifikasi pra-produksi yang realistis pada stack yang hampir sama dengan produksi.

Namun ada trade-off yang harus diterima:

  • Biaya infrastruktur bisa lebih tinggi karena dua environment hidup bersamaan.
  • State eksternal seperti database, cache, queue, object storage, dan event stream tetap perlu perhatian khusus.
  • Rollback aplikasi bisa cepat, tetapi rollback data sering kali tidak semudah membalik arah trafik.

Catatan penting: Blue-green deployment bukan jaminan aman jika perubahan skema database tidak backward-compatible. Banyak kegagalan deployment terjadi justru di lapisan data, bukan di layer routing trafik.

Urutan eksekusi blue-green deployment yang aman

Urutan deployment lebih penting daripada istilahnya. Blue-green yang dilakukan tanpa disiplin urutan tetap berisiko. Berikut alur yang umum dan aman untuk aplikasi web/backend.

1. Pastikan kandidat Green dibangun dari artefak yang immutable

Gunakan artefak yang bisa dilacak, misalnya image container atau paket rilis dengan identitas commit yang jelas. Hindari build langsung di server target jika ingin hasil deployment konsisten dan mudah diaudit.

Sebelum Green dijalankan, pastikan:

  • Konfigurasi environment sudah benar.
  • Secret tersedia dan dapat diakses proses aplikasi.
  • Versi dependency yang dipakai Green sama dengan hasil yang diuji sebelumnya.
  • Endpoint observabilitas aktif: metrics, logs, dan health endpoint.

2. Jalankan Green tanpa menerima trafik produksi penuh

Setelah artefak siap, start instance Green dan lakukan warm-up seperlunya:

  • inisialisasi koneksi database,
  • kompilasi cache atau template bila diperlukan,
  • pemanasan connection pool,
  • loading konfigurasi runtime.

Pada tahap ini, Green belum menjadi target utama trafik publik. Tujuannya agar masalah startup, dependency, atau konfigurasi muncul sebelum cutover.

3. Lakukan health check yang benar-benar merepresentasikan kesiapan

Kesalahan umum adalah menganggap proses hidup berarti aplikasi siap. Readiness check seharusnya membuktikan bahwa aplikasi benar-benar bisa melayani request penting, bukan hanya merespons 200 OK dari endpoint statis.

Health check sebelum cutover sebaiknya mencakup:

  • Liveness: proses utama hidup dan tidak macet.
  • Readiness: aplikasi siap menerima trafik.
  • Dependency checks: koneksi ke database, cache, atau service internal yang wajib tersedia.
  • Functional smoke checks: jalur request yang mewakili use case inti.

Contoh struktur endpoint readiness yang berguna:

GET /readyz

{
  "status": "ok",
  "checks": {
    "database": "ok",
    "cache": "ok",
    "migrations_compatible": "ok",
    "critical_dependency": "ok"
  }
}

Yang penting bukan formatnya, melainkan bahwa hasilnya benar-benar berasal dari pemeriksaan runtime yang relevan.

4. Verifikasi koneksi database dan kompatibilitas query

Sebelum cutover, Green harus membuktikan bahwa ia dapat:

  • membuka koneksi ke database produksi,
  • melakukan query baca yang representatif,
  • melakukan operasi tulis jika memang diperlukan oleh endpoint utama,
  • berjalan dengan skema yang saat ini aktif.

Verifikasi ini tidak harus berarti menembakkan beban besar ke database produksi, tetapi harus cukup untuk menangkap masalah seperti:

  • credential salah,
  • network policy atau firewall belum diperbarui,
  • pool size tidak sesuai,
  • query baru bergantung pada kolom/indeks yang belum ada,
  • timeout meningkat karena perubahan pola akses data.

Untuk aplikasi dengan queue worker atau job async, pastikan juga apakah Green akan langsung memproses queue saat cutover. Jika ya, cek kompatibilitas payload job, handler baru, dan idempoten saat terjadi rollback.

5. Jalankan smoke test terhadap jalur kritis

Minimal uji jalur yang paling menentukan kesehatan rilis:

  • login atau autentikasi service-to-service,
  • endpoint baca utama,
  • endpoint tulis utama,
  • akses ke cache/session,
  • publikasi atau konsumsi event bila ada.

Smoke test harus cepat, deterministik, dan tidak merusak data produksi. Untuk endpoint tulis, gunakan data uji yang aman dan bisa dibersihkan, atau gunakan operasi yang memang idempoten.

6. Alihkan trafik secara bertahap bila memungkinkan

Walaupun blue-green sering dipahami sebagai perpindahan sekali klik, pada praktiknya lebih aman jika ada fase pengamatan. Jika lapisan routing Anda mendukung pembagian trafik, arahkan sebagian kecil trafik ke Green dulu. Jika tidak mendukung, setidaknya lakukan cutover singkat dengan tim siaga dan dashboard observabilitas sudah terbuka.

Kriteria awal sebelum menerima trafik sebagian atau penuh:

  • semua readiness check lulus,
  • smoke test berhasil,
  • error startup tidak muncul di log,
  • tidak ada lonjakan restart container,
  • koneksi database stabil,
  • metrik dasar Green sebanding dengan Blue pada beban serupa.

Health check sebelum cutover: apa yang wajib ada

Health check yang baik harus membedakan antara aplikasi hidup dan aplikasi siap dipakai. Banyak insiden muncul karena load balancer mulai mengirim trafik saat proses baru selesai start, padahal koneksi dependency belum siap.

Liveness vs readiness

  • Liveness menjawab: apakah proses ini masih berjalan atau perlu direstart?
  • Readiness menjawab: apakah instance ini aman menerima request sekarang?

Jangan gabungkan keduanya secara sembarangan. Jika dependency sementara bermasalah, Anda mungkin ingin instance ditandai not ready, bukan terus direstart tanpa henti.

Apa yang sebaiknya diperiksa pada readiness

  • Koneksi database bisa dibuat dalam batas waktu wajar.
  • Query sederhana ke tabel yang benar-benar dipakai aplikasi berhasil.
  • Cache/session store tersedia jika request kritis membutuhkannya.
  • Secret dan konfigurasi wajib ter-load.
  • Versi migration yang dibutuhkan aplikasi sudah kompatibel.
  • Worker internal atau koneksi ke service penting sudah siap, jika request bergantung padanya.

Yang perlu dihindari:

  • Health endpoint yang selalu mengembalikan 200 tanpa memeriksa apa pun.
  • Readiness yang terlalu berat sampai justru menambah beban dependency.
  • Memeriksa terlalu banyak dependency non-kritis sehingga aplikasi dianggap tidak siap padahal jalur utama sebenarnya aman.

Mengelola migration database agar rollback tetap mungkin

Ini bagian paling krusial. Dalam blue-green deployment, aplikasi lama dan aplikasi baru sering harus bisa hidup bergantian untuk sementara. Artinya, perubahan skema database perlu dirancang agar backward-compatible dan idealnya juga forward-compatible selama masa transisi.

Prinsip migration aman untuk blue-green

  1. Ekspansi dulu, kontraksi belakangan. Tambahkan kolom, tabel, atau indeks baru terlebih dahulu. Jangan langsung hapus atau ubah perilaku kolom lama yang masih dipakai Blue.
  2. Deploy kode yang toleran terhadap dua skema. Green sebaiknya bisa berjalan meski data lama masih ada, dan Blue sebaiknya tidak rusak jika elemen skema baru sudah ditambahkan.
  3. Backfill secara terpisah. Jika perlu memindahkan data, lakukan sebagai job terpisah yang bisa dipantau, bukan sebagai langkah deployment yang panjang dan berisiko.
  4. Tunda perubahan destruktif. Menghapus kolom, mengganti tipe data secara agresif, atau membuat constraint baru yang berpotensi memblokir write sebaiknya dilakukan setelah rilis stabil.

Contoh pola expand-and-contract

Misalkan Anda ingin mengganti kolom full_name menjadi first_name dan last_name.

  1. Tambahkan kolom baru first_name dan last_name.
  2. Deploy aplikasi yang masih bisa membaca full_name tetapi mulai menulis ke skema baru, atau menulis ke keduanya untuk sementara.
  3. Lakukan backfill data lama ke kolom baru.
  4. Verifikasi semua pembaca sudah pindah ke kolom baru.
  5. Baru setelah stabil, hapus ketergantungan pada full_name dan lakukan migration destruktif di rilis berikutnya.

Pola ini memungkinkan rollback aplikasi tanpa langsung merusak kompatibilitas data.

Kapan migration dijalankan?

Tergantung sifat perubahannya, tetapi untuk perubahan yang aman dan backward-compatible, migration ekspansi biasanya dijalankan sebelum cutover. Tujuannya agar Green tidak bergantung pada perubahan yang belum ada saat trafik mulai masuk.

Hindari migration yang:

  • mengunci tabel besar terlalu lama,
  • mengubah data besar-besaran di jalur deployment sinkron,
  • tidak bisa dibatalkan atau diverifikasi dampaknya dengan cepat.

Aturan praktis: jika rollback aplikasi harus tetap mungkin, maka aplikasi lama tidak boleh langsung rusak hanya karena migration yang baru dijalankan.

Kapan traffic dialihkan penuh ke Green

Cutover penuh seharusnya menjadi keputusan yang berbasis sinyal. Jangan mengandalkan satu indikator saja, misalnya endpoint sehat atau container hidup.

Kriteria minimum sebelum full cutover

  • Readiness dan smoke test lulus konsisten beberapa kali.
  • Error rate pada Green tidak lebih buruk secara nyata dibanding Blue.
  • Latency p95 pada endpoint utama tidak menunjukkan regresi yang mengkhawatirkan.
  • Saturation pada CPU, memory, thread pool, connection pool, atau worker queue masih dalam batas aman operasional Anda.
  • Tidak ada lonjakan restart container atau crash loop.
  • Log tidak menunjukkan anomali baru yang berulang, terutama error dependency, timeout, serialization issue, atau database constraint failure.

Jika sistem Anda mendukung observasi per subset trafik, gunakan fase:

  1. 0% ke Green: validasi startup dan smoke test.
  2. sebagian kecil trafik: validasi metrik nyata pada beban produksi.
  3. naik bertahap sambil observasi metrik yang sama.
  4. 100% ke Green saat sinyal stabil.

Jika pembagian trafik bertahap tidak tersedia, siapkan rollback cepat sebelum cutover penuh: route lama masih aktif, artefak Blue tetap hidup, dan tim tahu siapa yang mengeksekusi pembalikan trafik.

Sinyal observabilitas wajib setelah cutover

Begitu trafik pindah ke Green, fase kritis berikutnya adalah observasi. Banyak bug tidak muncul saat smoke test, tetapi baru terlihat saat ada variasi request, concurrency, atau data riil.

1. Error rate

Pantau tingkat error total dan per endpoint penting. Pisahkan sebisa mungkin antara:

  • error aplikasi,
  • error dependency upstream/downstream,
  • client error yang memang normal,
  • server error yang menandakan regresi.

Pola yang perlu dicurigai:

  • lonjakan 5xx setelah cutover,
  • error hanya pada endpoint tulis,
  • peningkatan timeout,
  • database constraint violation yang sebelumnya tidak ada.

2. Latency p95

Rata-rata sering menipu. Pantau p95 latency untuk endpoint utama karena bottleneck biasanya muncul di ekor distribusi. Regresi p95 dapat mengindikasikan:

  • query database lebih lambat,
  • pool koneksi terlalu kecil,
  • blocking I/O baru,
  • serialisasi respons lebih berat,
  • kontensi lock atau thread.

Jika p95 naik tetapi error rate belum naik, itu sering menjadi sinyal dini sebelum insiden membesar.

3. Saturation

Saturation menunjukkan seberapa dekat resource terhadap kapasitas penuhnya. Ini bukan hanya CPU dan memory, tetapi juga:

  • connection pool database,
  • thread pool,
  • worker queue depth,
  • file descriptor,
  • rate limit dependency eksternal.

Masalah saturation sering menjelaskan kenapa health check awal terlihat baik, tetapi sistem memburuk saat menerima trafik penuh.

4. Restart container atau proses

Restart yang meningkat setelah cutover biasanya bukan kebetulan. Akar masalah yang umum:

  • memory leak atau penggunaan memory puncak lebih besar dari perkiraan,
  • readiness/liveness terlalu agresif,
  • dependency startup lambat sehingga instance dianggap gagal,
  • konfigurasi secret atau mount file tidak konsisten.

Perhatikan apakah restart terjadi pada semua instance atau hanya subset tertentu. Jika hanya sebagian, kemungkinan ada masalah node, konfigurasi, atau distribusi trafik yang tidak merata.

5. Anomali log

Log bukan sekadar tempat mencari stack trace setelah gagal. Selama beberapa menit pertama setelah cutover, cari pola baru yang berulang:

  • timeout ke database atau service internal,
  • deserialization atau schema mismatch,
  • cache miss berlebihan yang memicu lonjakan beban database,
  • permission denied, credential invalid, atau certificate issue,
  • constraint violation saat write.

Fokus pada error yang baru muncul setelah cutover dan berkorelasi dengan penurunan metrik. Jangan tenggelam dalam noise yang memang sudah ada sebelumnya.

Runbook rollback cepat

Rollback yang baik bukan keputusan spontan tanpa prosedur. Ia harus menjadi langkah yang sudah dilatih dan dapat dijalankan dengan cepat. Tujuan utama rollback adalah mengembalikan layanan stabil lebih dulu, baru kemudian analisis akar masalah.

Kapan rollback harus dipilih

Pilih rollback jika salah satu kondisi ini terjadi dan tidak ada mitigasi cepat yang aman:

  • error rate meningkat jelas setelah cutover,
  • latency p95 naik signifikan pada jalur penting,
  • restart container meningkat atau crash loop muncul,
  • terjadi kegagalan write ke database,
  • anomali log menunjukkan masalah sistemik, bukan kasus sporadis.

Langkah rollback praktis

  1. Hentikan eskalasi risiko: pause rollout lanjutan, hentikan autoscaling agresif jika justru memperparah.
  2. Alihkan trafik kembali ke Blue: lakukan perubahan routing atau target upstream agar Blue kembali menerima trafik produksi.
  3. Pastikan Blue benar-benar sehat: verifikasi metrik dan health check Blue setelah trafik kembali.
  4. Isolasi Green: biarkan tetap hidup jika perlu untuk forensik, tetapi jangan menerima trafik produksi utama.
  5. Cek integritas data: pastikan write yang sempat masuk ke Green tidak meninggalkan inkonsistensi yang perlu ditangani.
  6. Bekukan migration destruktif: jika ada langkah lanjutan yang belum dijalankan, jangan lanjutkan.
  7. Komunikasikan status: catat waktu cutover, waktu rollback, gejala, metrik yang terdampak, dan mitigasi yang dilakukan.

Jika deployment melibatkan worker async, evaluasi apakah worker Green juga perlu dinonaktifkan saat rollback. Kadang web traffic sudah balik ke Blue, tetapi worker Green masih memproses payload dengan asumsi skema baru sehingga masalah belum benar-benar selesai.

Contoh checklist rollback

- Routing sudah dikembalikan ke Blue
- Blue lulus readiness check
- Error rate kembali ke baseline operasional
- p95 endpoint utama membaik
- Tidak ada crash loop pada Blue
- Worker/consumer yang tidak kompatibel sudah dihentikan
- Tidak ada migration destruktif lanjutan yang berjalan
- Log dan metrik Green disimpan untuk analisis

Akar masalah yang umum pada blue-green deployment

Sebagian besar insiden deployment berulang di pola yang sama. Berikut root cause yang paling sering muncul.

1. Health check terlalu dangkal

Endpoint mengembalikan 200, tetapi koneksi database sebenarnya gagal saat request nyata datang. Solusinya adalah readiness check yang memverifikasi dependency kritis secara ringan namun bermakna.

2. Perubahan database tidak backward-compatible

Aplikasi baru mengandalkan skema baru, tetapi rollback ke aplikasi lama jadi mustahil atau aplikasi lama langsung rusak. Solusinya adalah pola expand-and-contract dan disiplin memisahkan perubahan destruktif.

3. Perbedaan konfigurasi antara Blue dan Green

Sering kali image aplikasi benar, tetapi environment variable, secret, policy jaringan, atau setting pool berbeda. Solusinya: treat configuration as code, review config diff sebelum cutover, dan validasi runtime di Green.

4. Queue, cache, atau session tidak diperhitungkan

Deployment terlihat sehat pada request sinkron, tetapi worker gagal memproses job karena payload berubah atau session store tidak kompatibel. Solusinya: masukkan komponen async dan stateful ke checklist deployment.

5. Beban nyata berbeda dari smoke test

Startup dan smoke test lolos, tetapi setelah trafik penuh masuk, saturation terjadi di connection pool atau query path tertentu. Solusinya: observasi bertahap, pantau p95 dan saturation, bukan hanya status hidup.

Checklist pasca-insiden ringan

Jika sempat terjadi gangguan singkat saat cutover atau rollback, lakukan review ringan sesegera mungkin. Tujuannya bukan mencari kambing hitam, melainkan memperbaiki proses deployment berikutnya.

Checklist yang disarankan

  • Apa gejala pertama yang terlihat: error rate, latency, restart, atau log?
  • Apakah alarm berbunyi cukup cepat dan relevan?
  • Apakah keputusan rollback diambil dengan kriteria yang jelas?
  • Berapa lama dari cutover ke deteksi masalah?
  • Berapa lama dari deteksi ke rollback efektif?
  • Apakah health check gagal menangkap masalah yang sebenarnya?
  • Apakah migration atau perubahan schema berkontribusi?
  • Apakah ada gap observabilitas, misalnya metrik penting belum tersedia?
  • Apakah runbook dijalankan sesuai prosedur atau masih mengandalkan ingatan orang tertentu?
  • Perubahan apa yang harus ditambahkan ke checklist deployment selanjutnya?

Tindakan pencegahan agar deployment berikutnya lebih aman

Blue-green deployment aman bukan karena nama metodenya, tetapi karena disiplin operasional dan desain perubahan yang kompatibel.

Praktik pencegahan yang efektif

  • Gunakan readiness check yang bermakna, bukan endpoint kosong.
  • Rancang migration database untuk rollback dengan prinsip expand-and-contract.
  • Pisahkan perubahan besar: jangan gabungkan refactor query, migration data besar, dan perubahan dependency dalam satu rilis jika bisa dihindari.
  • Latih rollback secara berkala agar tim tidak baru belajar saat insiden terjadi.
  • Siapkan dashboard cutover yang menampilkan error rate, p95, saturation, restart, dan log anomali dalam satu tempat.
  • Pastikan artefak dan konfigurasi dapat dilacak agar root cause lebih cepat ditemukan.
  • Definisikan kriteria go/no-go sebelum deployment dimulai, termasuk ambang kapan rollback harus dilakukan.
  • Perhatikan komponen async seperti queue consumer, cron, atau event processor, bukan hanya web instance.

Penutup

Blue-green deployment memberi keuntungan besar untuk cutover aman dan rollback cepat, tetapi hanya jika Anda memperlakukan health check, database compatibility, dan observabilitas sebagai bagian inti dari proses deployment. Fokus utamanya bukan sekadar memindahkan trafik, melainkan memastikan versi baru benar-benar siap, dapat dipantau, dan dapat ditinggalkan dengan cepat jika sinyal pasca-cutover menunjukkan masalah.

Jika Anda ingin deployment lebih aman, mulailah dari hal paling mendasar: urutan eksekusi yang disiplin, readiness check yang realistis, migration yang tidak memutus rollback, dan runbook rollback yang bisa dijalankan tanpa debat panjang. Di situlah blue-green deployment benar-benar memberikan nilai operasional.