Mengapa Aplikasi Anda Berperilaku Berbeda di Staging dan Production

Anda men-deploy kode yang sama ke staging, menjalankan pengujian, semuanya lolos. Kemudian Anda men-deploy ke production, dan aplikasi crash. Kodenya identik. Perbedaannya hanya satu nilai konfigurasi yang lupa Anda perbarui.

Skenario ini terjadi di banyak tim setiap minggu. Kode tidak bermasalah. Konfigurasinya yang salah. Dan ketika masalahnya adalah secret seperti kata sandi database atau token API, risikonya semakin tinggi. Secret yang bocor bisa menyebabkan kerusakan lebih besar daripada kebanyakan bug kode.

Apa Sebenarnya Konfigurasi dan Secret Itu

Konfigurasi adalah nilai apa pun yang mengubah perilaku aplikasi tanpa mengubah kodenya. Alamat server, jumlah koneksi maksimum, level logging, fitur flag — semuanya adalah konfigurasi. Codebase yang sama berjalan berbeda di development, staging, dan production karena konfigurasinya berubah.

Secret adalah kategori khusus dari konfigurasi. Nilai-nilai ini harus tetap rahasia: kata sandi, token, kunci enkripsi, sertifikat. Secret membutuhkan penanganan berbeda karena kebocorannya adalah insiden keamanan, bukan sekadar kesalahan konfigurasi.

Poin utamanya adalah bahwa konfigurasi dan secret perlu dikelola secara terpisah dari kode aplikasi. Keduanya berada di lapisan yang berbeda dalam sistem pengiriman Anda.

Mulai dengan Template Konfigurasi

Sebelum Anda dapat mengelola konfigurasi dengan benar, Anda perlu tahu konfigurasi apa yang sebenarnya dibutuhkan aplikasi Anda. Template konfigurasi hanyalah daftar lengkap setiap nilai konfigurasi yang diharapkan aplikasi Anda, diorganisir berdasarkan lingkungan.

Untuk setiap item konfigurasi, catat:

Berikut contoh konkret seperti apa template tersebut dalam YAML:

# config-template.yaml
# Template konfigurasi aplikasi
# Timpa nilai per lingkungan di file khusus lingkungan

app:
  name: my-app
  version: 1.0.0
  log_level: info  # timpa: dev=debug, staging=info, prod=warn
  max_retry: 3

database:
  host: localhost  # timpa: staging=db-staging.example.com, prod=db-prod.example.com
  port: 5432
  name: myapp_db
  pool_size: 10  # timpa: prod=50

cache:
  host: localhost  # timpa: staging=redis-staging.example.com, prod=redis-prod.example.com
  port: 6379
  ttl_seconds: 3600

feature_flags:
  new_checkout: false  # timpa: staging=true, prod=false
  dark_mode: true
  • Nama variabel (seperti DB_HOST atau MAX_RETRY)
  • Tipe nilai (string, angka, boolean)
  • Lingkungan mana yang menggunakannya
  • Apakah nilainya berbeda antar lingkungan

Beberapa nilai akan sama di mana-mana. MAX_RETRY mungkin 3 di development, staging, dan production. Nilai lain harus berbeda. DB_HOST akan menunjuk ke database lokal Anda di development dan ke kluster database production di production.

Template juga harus mencatat siapa yang dapat mengubah setiap nilai konfigurasi dan bagaimana perubahan tersebut dilacak. Tidak semua orang di tim harus bisa mengubah string koneksi database production.

Secret Membutuhkan Template Sendiri

Secret mengikuti ide yang sama tetapi dengan aturan yang lebih ketat. Template secret mencatat:

  • Nama secret
  • Dari mana asalnya (vault, parameter store, file terenkripsi)
  • Lingkungan mana yang membutuhkan akses ke sana
  • Kapan terakhir dirotasi
  • Berapa lama masa berlakunya
  • Langkah-langkah tepat untuk merotasinya
  • Cara memverifikasi aplikasi masih berfungsi setelah rotasi

Rotasi adalah proses mengganti secret lama dengan yang baru secara terjadwal. Banyak tim melewatkan ini sampai terjadi pelanggaran yang memaksa mereka bertindak. Template membuat rotasi menjadi operasi rutin, bukan keadaan darurat.

Langkah verifikasi sangat penting. Setelah merotasi kata sandi database, Anda perlu memastikan aplikasi masih bisa terhubung dan melakukan query data. Jika tidak, Anda mungkin merotasi secret dan merusak production tanpa sadar sampai pengguna mulai melaporkan error.

Audit Semuanya

Konfigurasi dan secret membutuhkan jejak audit. Log audit mencatat siapa yang mengakses atau mengubah nilai konfigurasi atau secret, kapan mereka melakukannya, dan mengapa.

Template untuk log audit harus menangkap:

  • Stempel waktu tindakan
  • Siapa yang melakukannya
  • Tindakan apa yang diambil (lihat, ubah, hapus)
  • Konfigurasi atau secret mana yang terpengaruh

Log ini sangat penting ketika terjadi masalah. Jika secret bocor, Anda perlu tahu siapa yang mengaksesnya dan kapan. Jika perubahan konfigurasi merusak production, Anda perlu melacak siapa yang membuat perubahan dan apa nilai sebelumnya.

Tanpa log audit, Anda melakukan debugging secara buta. Anda tahu ada yang berubah, tetapi tidak ada cara untuk mencari tahu apa atau siapa penyebabnya.

Uji Konfigurasi dan Secret Anda

Ini langkah yang sering diabaikan oleh sebagian besar tim: konfigurasi dan secret perlu diuji. Anda menguji kode. Anda menguji infrastruktur. Tapi seberapa sering Anda menguji bahwa aplikasi Anda benar-benar dapat membaca konfigurasi dan secret dengan benar di setiap lingkungan?

Pengujian konfigurasi memverifikasi bahwa:

  • Semua nilai konfigurasi yang diperlukan ada
  • Nilai-nilai tersebut memiliki tipe yang benar
  • Nilai-nilai tersebut berada dalam rentang yang diharapkan
  • Aplikasi berhasil dimulai dengan nilai-nilai ini

Pengujian secret memverifikasi bahwa:

  • Secret ada dan dapat diakses
  • Aplikasi dapat melakukan autentikasi menggunakan secret
  • Aplikasi dapat melakukan operasi dasarnya setelah autentikasi

Pengujian ini menangkap masalah sebelum deployment. Secret yang hilang atau nilai konfigurasi yang salah format akan menyebabkan aplikasi crash saat startup. Lebih baik menangkapnya dalam pengujian daripada di production.

Daftar Periksa Praktis

Berikut daftar periksa singkat yang dapat Anda gunakan saat menyiapkan manajemen konfigurasi dan secret untuk aplikasi atau layanan baru:

  • Daftar semua nilai konfigurasi yang dibutuhkan aplikasi, diorganisir berdasarkan lingkungan
  • Catat nilai mana yang berbeda antar lingkungan dan mana yang tetap sama
  • Identifikasi nilai mana yang merupakan secret dan membutuhkan penanganan khusus
  • Dokumentasikan sumber setiap secret (vault, parameter store, dll.)
  • Buat jadwal rotasi untuk setiap secret
  • Siapkan logging audit untuk akses konfigurasi dan secret
  • Tulis pengujian yang memverifikasi pemuatan konfigurasi dan secret di setiap lingkungan
  • Dokumentasikan siapa yang dapat mengubah setiap nilai konfigurasi dan secret

Kesimpulan

Konfigurasi dan secret bukanlah hal yang dipikirkan belakangan. Keduanya adalah concern terpisah yang membutuhkan template sendiri, pengujian sendiri, dan jejak audit sendiri. Kode yang sama yang berfungsi sempurna di staging akan gagal di production jika satu nilai konfigurasi salah atau satu secret hilang. Perlakukan konfigurasi dan secret dengan ketelitian yang sama seperti Anda memperlakukan kode aplikasi, dan Anda akan menghilangkan seluruh kategori kegagalan deployment.