Hentikan konfigurasi manual lewat UI yang rentan salah, kelola seluruh controller lewat file jenkins.yaml, dan provisi Jenkins identik secara instan memakai Docker serta JCasC.

Di episode 12 kita menghilangkan kredensial statis dengan OIDC. Sekarang mari kita lihat masalah lain yang tak kalah besar: bagaimana konfigurasi Jenkins itu sendiri dikelola.
Sebagian besar Jenkins di dunia dikonfigurasi manual lewat admin UI — klik sana, klik sini, isi form, simpan. Pendekatan yang sering disebut Configuration ClickOps ini rapuh. Tidak ada jejak audit siapa mengubah apa, satu pilihan yang salah di form bisa merusak controller, dan saat server mati atau lingkungan harus dibangun ulang, semua konfigurasi harus diulang dari nol dengan ingatan belaka. Bayangkan harus menginstall ulang laptop dari nol tanpa catatan aplikasi apa yang pernah terpasang — itulah ClickOps saat disaster recovery.
Solusinya adalah Jenkins Configuration as Code (JCasC): seluruh konfigurasi controller ditulis sebagai file deklaratif bernama jenkins.yaml, disimpan di repository Git, dan diterapkan otomatis saat Jenkins dinyalakan. Di episode ini kita akan membangun Jenkins yang sepenuhnya ditentukan oleh kode — lengkap dengan keamanan, kredensial, tools, dan plugin.
Konfigurasi manual lewat UI memiliki tiga kelemahan fundamental:
JCasC mengubah file konfigurasi menjadi satu-satunya sumber kebenaran (single source of truth). Perubahan dilakukan lewat pull request, bisa di-review, bisa diuji, dan menghasilkan Jenkins yang identik di lingkungan mana pun.
Plugin Configuration as Code membuat Jenkins dapat menerima seluruh konfigurasi dalam satu file YAML, mencakup: system settings, security realm, authorization strategy, credentials, nodes, tools seperti JDK dan Maven, hingga pengaturan plugin. Lokasi file-nya diberikan melalui environment variable CASC_JENKINS_CONFIG — bisa satu file atau satu direktori berisi banyak file YAML yang digabungkan.
Saat Jenkins pertama kali boot, JCasC membaca file tersebut dan menerapkan seluruh pengaturan secara otomatis. Ada satu batasan penting yang harus dipahami:
Note
JCasC mengelola konfigurasi controller — bukan definisi job. Job pipelines tetap hidup di masing-masing repository (Pipeline as Code). Untuk mendeklarasikan job terpusat, gabungkan dengan plugin Job DSL atau jenkins-jobs.yaml.
Berikut contoh jenkins.yaml yang mendeklarasikan keamanan, kredensial, dan tool dalam satu file:
jenkins:
systemMessage: "Jenkins dikelola dengan JCasC - jangan ubah manual!"
numExecutors: 0
authorizationStrategy:
globalMatrix:
permissions:
- "Overall/Administer:admin"
- "Overall/Read:authenticated"
- "Job/Read:developer"
securityRealm:
local:
allowsSignup: false
credentials:
system:
domainCredentials:
- credentials:
- usernamePassword:
scope: GLOBAL
id: docker-hub
username: "${DOCKERHUB_USERNAME}"
password: "${DOCKERHUB_PASSWORD}"
- basicSSHUserPrivateKey:
scope: GLOBAL
id: deploy-key
username: deploy
privateKeySource:
directEntry:
privateKey: "${DEPLOY_PRIVATE_KEY}"
tools:
jdk:
installations:
- name: jdk17
properties:
- installSource:
installers:
- jdkInstaller:
version: "17"
unclassified:
location:
url: "https://jenkins.example.com"
gitSCM:
globalConfigName: "jenkins-bot"
globalConfigEmail: "jenkins@example.com"Perhatikan nilai seperti numExecutors: 0 — controller tidak menjalankan build apa pun, semua pekerjaan diarahkan ke agent, sesuai prinsip keamanan controller. Nilai kredensial diambil dari environment variable — JCasC mengganti referensi variabel lingkungan di dalam file YAML saat controller boot — sehingga secret tidak pernah tertulis di repository.
Warning
Jangan menulis nilai secret secara langsung di jenkins.yaml yang masuk ke Git. Selalu referensikan environment variable, dan set nilai variabelnya saat container dijalankan. Secret di repository adalah celah keamanan yang permanen.
Instalasi plugin juga bisa dideklarasikan lewat file plugins.txt — satu baris per plugin beserta versinya:
configuration-as-code:1817.vf64c293ec5c1
role-strategy:753.v9ee33920c17a
openid-connect-plugin:2.11.0-1
git:5.6.0
workflow-aggregator:600.vb_57cdd26fdd7
junit:1301.v7396a_4306d48Daftar ini menjadi kontrak versi: setiap image Jenkins dibangun dengan kombinasi plugin yang sama persis, sehingga perilaku antar environment tidak melenceng.
Gabungkan JCasC dengan Docker untuk menciptakan immutable controller: image yang berisi seluruh konfigurasi dan plugin, siap dijalankan ulang kapan pun. Contoh Dockerfile:
FROM jenkins/jenkins:lts-jdk17
COPY --chown=jenkins:jenkins jenkins.yaml /var/jenkins_home/jenkins.yaml
ENV CASC_JENKINS_CONFIG=/var/jenkins_home/jenkins.yaml
COPY --chown=jenkins:jenkins plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN jenkins-plugin-cli -f /usr/share/jenkins/ref/plugins.txtBangun image lalu jalankan container sambil menyuplai secret lewat environment variable:
docker build -t my-jenkins:1.0 .
docker run -d -p 8080:8080 \
-e CASC_JENKINS_CONFIG=/var/jenkins_home/jenkins.yaml \
-e DOCKERHUB_USERNAME=arman \
-e DOCKERHUB_PASSWORD=rahasia \
-e DEPLOY_PRIVATE_KEY="$(cat ~/.ssh/id_ed25519)" \
-v jenkins-home:/var/jenkins_home \
my-jenkins:1.0Dalam hitungan detik, Jenkins yang baru menyalakan controller dengan konfigurasi, keamanan, kredensial, dan plugin yang identik. Inilah kekuatan utama JCasC: reproducibility.
Karena konfigurasi hidup di Git, setiap perubahan bisa di-review dan menjadi jejak audit. Jika controller rusak, pemulihannya sederhana: bangun ulang image, restore backup JENKINS_HOME, dan controller kembali dalam kondisi yang sama. Tidak ada lagi proses menebak-nebak pengaturan saat server produksi tumbang.
Tip
Jika kalian sudah punya Jenkins yang dikonfigurasi manual, gunakan
halaman Manage Jenkins > Configuration as Code untuk melihat
representasi YAML dari konfigurasi saat ini sebagai titik awal menulis
jenkins.yaml. Setelah JCasC aktif, hindari mengubah pengaturan lewat UI
karena hasilnya akan ditimpa pada reload berikutnya.
Pada episode 13 ini kalian telah memahami mengapa Configuration ClickOps berbahaya, konsep JCasC yang mengelola seluruh controller lewat jenkins.yaml, deklarasi plugin memakai plugins.txt, dan cara menggabungkan Docker dengan JCasC untuk menciptakan controller immutable yang identik dalam hitungan detik. Kalian juga tahu bahwa konfigurasi kini bisa diaudit lewat Git dan dipulihkan dengan mudah saat bencana.
Sampai di sini, infrastruktur CI/CD kalian sudah aman dan terotomatisasi. Namun satu pertanyaan penting masih tersisa: apakah kode yang di-build benar-benar berkualitas?
Di episode 14 berikutnya kita akan membahas Automated Testing, Code Quality & SonarQube Integration — mempublikasikan hasil test, mengukur coverage, dan menghentikan pipeline otomatis jika kode gagal memenuhi standar kualitas. Sampai jumpa!