Memperluas CI/CD ke Database dan Infrastruktur: Peta Jalan Praktis

Pipeline aplikasi Anda sudah berjalan mulus. Perubahan kode mengalir dari commit ke produksi dengan pengujian otomatis, build, dan deployment. Tim merasa percaya diri saat mendorong pembaruan. Tapi ada masalah: perubahan skema database masih terjadi melalui seseorang yang menjalankan skrip SQL langsung di produksi, dan infrastruktur dikonfigurasi dengan login ke konsol cloud dan mengklik tombol.

Kesenjangan ini menimbulkan gesekan. Seorang developer menambahkan kolom baru ke tabel, tapi skrip migrasi dikirim melalui email ke DBA yang menjalankannya secara manual. Sebuah server membutuhkan perubahan konfigurasi, tapi seseorang harus SSH dan mengedit file. Langkah-langkah manual ini mematahkan konsistensi yang telah Anda bangun di tempat lain. Langkah-langkah ini memperkenalkan risiko, tidak memiliki jejak audit, dan membuat rollback hampir mustahil.

Kabar baiknya adalah prinsip pipeline yang sama berlaku untuk database dan infrastruktur. Perbedaannya ada pada detailnya: apa yang Anda uji, bagaimana Anda mengelola risiko, dan bagaimana Anda menangani rollback.

Membawa Migrasi Database ke Dalam Pipeline

Perubahan database berbeda dari kode aplikasi karena beroperasi pada data langsung. Bug di kode aplikasi mungkin menyebabkan error yang mudah diperbaiki. Migrasi yang buruk dapat merusak atau menghapus data secara permanen. Realitas ini membuat tim ragu untuk mengotomatiskan deployment database, tapi alternatifnya—eksekusi manual—lebih buruk.

Mulailah dengan memperlakukan setiap perubahan skema sebagai kode. Setiap migrasi harus berupa skrip yang disimpan di version control, baik di repositori yang sama dengan aplikasi Anda atau di repositori khusus. Skrip harus memiliki versi yang jelas, deskripsi tentang apa yang dilakukannya, dan skrip rollback yang sesuai.

Sebagai contoh, migrasi untuk menambahkan kolom mungkin terlihat seperti ini:

-- V002__add_status_column.sql
-- Forward migration: add a status column with a default value
ALTER TABLE users ADD COLUMN status VARCHAR(20) NOT NULL DEFAULT 'active';
-- V002__add_status_column_rollback.sql
-- Rollback migration: remove the status column
ALTER TABLE users DROP COLUMN status;

Diagram berikut mengilustrasikan bagaimana tahapan database dan infrastruktur masuk ke dalam pipeline Anda yang sudah ada:

flowchart TD A[Code Commit] --> B[Build & Unit Tests] B --> C[Application Deploy to Staging] C --> D[Database Migration Dry Run] D --> E[Infrastructure Provisioning] E --> F[Integration Tests] F --> G{Approval Gate?} G -- Yes --> H[Production Deploy] G -- No --> I[Rollback] H --> J[Database Migration Apply] J --> K[Infrastructure Apply] K --> L[Smoke Tests] L -- Pass --> M[Deploy Complete] L -- Fail --> I I --> N[Restore Previous State]

Pipeline Anda kemudian menjalankan migrasi ini secara otomatis di berbagai lingkungan: development, staging, dan produksi. Tapi karena taruhannya lebih tinggi, Anda memerlukan gerbang tambahan:

  • Dry run di staging: Sebelum menjalankan migrasi di produksi, jalankan di staging dengan volume data yang mencerminkan produksi. Ini menangkap masalah performa dan perilaku locking yang tidak terduga.
  • Tes kompatibilitas: Periksa apakah migrasi bekerja dengan data yang sudah ada. Migrasi yang menambahkan kolom NOT NULL tanpa nilai default akan gagal jika baris yang ada memiliki nilai NULL di kolom tersebut.
  • Gerbang persetujuan untuk perubahan destruktif: Menghapus kolom, mengubah tipe data, atau menghapus tabel harus memerlukan persetujuan manual. Perubahan ini lebih sulit atau tidak mungkin untuk dibalikkan.

Setiap migrasi harus memiliki skrip rollback yang teruji. Menambahkan kolom biasanya aman untuk dibalikkan. Menghapus tabel tidak. Pipeline Anda harus dapat mengeksekusi rollback secara otomatis jika migrasi gagal atau jika tim memutuskan untuk kembali.

Infrastructure as Code: Deklarasikan, Jangan Klik

Infrastruktur mencakup server, jaringan, load balancer, instance database, dan setiap komponen yang dibutuhkan aplikasi Anda untuk berjalan. Ketika Anda menyediakan ini secara manual melalui konsol cloud, Anda menciptakan beberapa masalah:

  • Lingkungan menyimpang. Development mungkin memiliki pengaturan yang sedikit berbeda dari produksi.
  • Perubahan sulit direproduksi. Jika server crash, bisakah Anda membuat ulang persis sama?
  • Tidak ada jejak audit. Siapa yang mengubah aturan firewall minggu lalu?

Solusinya adalah mendeklarasikan infrastruktur Anda sebagai kode. Tulis file konfigurasi yang menjelaskan bagaimana infrastruktur Anda seharusnya terlihat, lalu biarkan pipeline menerapkan konfigurasi tersebut. Ini disebut infrastructure as code (IaC).

Alat seperti Terraform, AWS CloudFormation, atau Pulumi memungkinkan Anda mendefinisikan resource dalam file. File-file ini melalui pipeline yang sama dengan kode aplikasi Anda: masuk ke repositori, menjalani code review, diuji di development, lalu diterapkan ke staging dan produksi.

Menguji infrastruktur berbeda dari menguji aplikasi. Tes aplikasi memeriksa apakah kode berperilaku benar. Tes infrastruktur memeriksa apakah konfigurasi menghasilkan lingkungan yang diharapkan:

  • Apakah port yang diperlukan terbuka?
  • Apakah firewall dikonfigurasi dengan benar?
  • Apakah versi sistem operasi benar?
  • Apakah ukuran resource (CPU, memori, disk) sesuai spesifikasi?

Beberapa tim melangkah lebih jauh dengan menyediakan infrastruktur di lingkungan terisolasi, menjalankan tes terhadapnya, lalu menghancurkannya. Ini memberikan keyakinan tinggi sebelum menerapkan perubahan ke produksi.

Gerbang risiko untuk infrastruktur mengikuti pola yang sama dengan database. Perubahan yang menyesuaikan ukuran disk mungkin hanya memerlukan tes otomatis. Perubahan yang merestrukturisasi jaringan atau mengganti tipe database memerlukan persetujuan manual dan validasi yang lebih menyeluruh.

Strategi Rollback untuk Database dan Infrastruktur

Rollback kode aplikasi biasanya mudah: deploy versi sebelumnya. Rollback migrasi database atau perubahan infrastruktur memerlukan lebih banyak perencanaan.

Untuk migrasi database, skrip rollback harus ditulis bersamaan dengan migrasi forward. Uji rollback di pipeline Anda, bukan hanya di kepala Anda. Beberapa migrasi bersifat aditif (menambahkan kolom) dan rollback dengan bersih. Yang lain bersifat transformatif (memisahkan tabel) dan memerlukan logika rollback yang hati-hati. Jika migrasi tidak dapat di-rollback dengan aman, itu adalah sinyal untuk mendesain ulang pendekatan migrasi.

Untuk infrastruktur, pipeline Anda harus menyimpan status konfigurasi sebelumnya. Ketika Anda perlu rollback, pipeline menerapkan konfigurasi sebelumnya. Ini bekerja dengan baik untuk alat IaC deklaratif karena mereka menangani perbedaan antara status saat ini dan yang diinginkan secara otomatis.

Daftar Periksa Praktis untuk Memperluas Pipeline Anda

Area Apa yang Ditambahkan Gerbang Risiko Rollback
Database Skrip migrasi di version control Dry run di staging, persetujuan untuk perubahan destruktif Skrip rollback teruji per migrasi
Infrastruktur File konfigurasi IaC Validasi otomatis, persetujuan untuk perubahan arsitektur Konfigurasi sebelumnya disimpan dan dapat di-deploy

Polanya Berulang

Setelah Anda memiliki database dan infrastruktur di pipeline, Anda akan melihat pola yang sama berlaku untuk area lain: konfigurasi lingkungan, feature flag, rilis aplikasi seluler. Detailnya berubah—apa yang Anda uji, bagaimana Anda mengelola risiko, bagaimana Anda rollback—tapi ide intinya tetap sama. Setiap perubahan mengikuti jalur yang konsisten, teruji, dan dapat dibalikkan.

Mulailah dengan satu migrasi database di pipeline Anda. Lalu satu perubahan infrastruktur. Beberapa yang pertama akan terasa lambat karena Anda sedang membangun prosesnya. Tapi masing-masing membuat yang berikutnya lebih cepat dan lebih aman.

Tujuannya bukan otomatisasi demi otomatisasi itu sendiri. Tujuannya adalah memastikan bahwa ketika sesuatu rusak—dan pasti akan rusak—Anda tahu persis apa yang berubah, bagaimana memperbaikinya, dan bagaimana mencegahnya terjadi lagi.