Mengelola nilai dalam pipeline: predefined variables bawaan GitLab dan custom CI/CD variables, memahami flags keamanan protected, masked, dan expand, lalu mengambil secret secara aman dari HashiCorp Vault langsung di .gitlab-ci.yml dengan id_tokens.

Di episode 4 kalian sudah bisa mengontrol kapan job dan pipeline berjalan dengan rules dan workflow. Sekarang giliran pertanyaan paling penting dalam pipeline produksi: bagaimana pipeline "tahu" hal-hal tentang konteksnya — commit mana, branch apa, nomor build berapa — dan bagaimana menyimpan data rahasia seperti API key atau password database tanpa bocor.
Jawabannya ada pada variables dan secret management. Memahami keduanya adalah titik di mana pipeline kalian berubah dari "skrip yang dijalankan GitLab" menjadi "program yang cerdas dan aman".
GitLab menyuntikkan puluhan variabel bawaan ke setiap job. Nilainya tidak perlu kalian set — GitLab yang mengisinya otomatis. Yang paling sering dipakai:
| Variabel | Isi |
|---|---|
$CI_COMMIT_SHA | Hash commit yang sedang diproses |
$CI_COMMIT_REF_NAME | Nama branch atau tag yang sedang diproses |
$CI_COMMIT_BRANCH | Nama branch (kosong untuk tag) |
$CI_PROJECT_DIR | Lokasi repository yang di-checkout di runner |
$CI_PROJECT_PATH | Path project, misal mygroup/my-app |
$CI_PIPELINE_ID | ID unik pipeline |
$CI_PIPELINE_SOURCE | Asal pipeline: push, merge_request_event, schedule, dll |
$CI_JOB_TOKEN | Token khusus job untuk autentikasi ke GitLab API |
Contoh pemakaian nyata — menamai image Docker agar unik per commit:
build:
stage: build
script:
- echo "Image tag: $CI_COMMIT_SHA"
- echo "Branch : $CI_COMMIT_REF_NAME"Bayangkan betapa berbahayanya jika tag image tidak unik: dua commit berbeda bisa menimpa image yang sama dan deployment menyesatkan. Dengan $CI_COMMIT_SHA, setiap build punya identitas yang tidak bisa disalahartikan.
Selain predefined, kalian bisa membuat variabel sendiri. Ada tiga tempat dengan prioritas berbeda:
Settings → CI/CD → Variables. Berlaku untuk satu project, nilainya bisa diubah dari UI tanpa commit. Nilai di sini mengalahkan nilai di file.Group → Settings → CI/CD → Variables. Berlaku untuk semua project dalam satu group; bisa di-override di level project..gitlab-ci.yml — dideklarasikan dengan keyword variables, baik global maupun per job.variables:
APP_ENV: production
MAX_RETRY: 3
deploy:
stage: deploy
variables:
DEPLOY_USER: deployer
script:
- echo "Environment: $APP_ENV"
- echo "User: $DEPLOY_USER"variables global berlaku untuk semua job, sedangkan variables di dalam sebuah job meng-override nilai global untuk job itu saja. Ingat urutan prioritasnya: variabel dari UI project settings menang, lalu group settings, lalu yang di dalam file.
Saat membuat variabel dari UI project settings, ada tiga toggle yang wajib dipahami:
main). Ini mencegah nilai produksi bocor ke pipeline branch fitur yang sedang dikembangkan sembarangan.REGISTRY_IMAGE=$CI_REGISTRY_IMAGE/my-app hanya berfungsi jika Expand diaktifkan.| Flag | Fungsi |
|---|---|
| Protected | Hanya untuk protected branches dan tags |
| Masked | Tersembunyi (asterisk) di log output |
| Expand | Mengizinkan ekspansi variabel dalam nilai |
Warning
Masked bukan enkripsi — nilainya tetap terlihat oleh user yang punya akses ke project. Untuk secret yang membutuhkan rotasi terpusat dan audit ketat, jangan menyimpannya di variabel GitLab. Gunakan external secret manager seperti HashiCorp Vault.
Masalah dengan variabel CI/CD: secret tersimpan di GitLab, tersebar di banyak project, sulit dirotasi, dan minim audit. Solusi industri adalah HashiCorp Vault — secret manager terpusat tempat secret disimpan dan diambil sesuai kebijakan. GitLab bisa mengambil secret langsung dari Vault saat job berjalan, tanpa menyimpan nilai secret di GitLab sama sekali.
Langkah pertama di sisi Vault: aktifkan JWT auth dan buat role yang mengikat project GitLab tertentu:
vault auth enable jwt
vault write auth/jwt/role/gitlab-ci \
bound_issuer="https://gitlab.example.com" \
bound_audiences="https://gitlab.example.com" \
user_claim="sub" \
bound_subject="project_path:myorg/myapp:*" \
token_policies="ci-app" \
token_ttl="10m"Penjelasan singkat: bound_issuer dan bound_audiences mencocokkan klaim JWT yang diterbitkan GitLab, sedangkan bound_subject mengikat role ke project myorg/myapp — tanda * di akhir memperbolehkan semua branch project tersebut.
Di sisi GitLab, beri tahu lokasi Vault dan role yang dipakai. Masuk ke Project → Settings → CI/CD → Vault server, lalu isi:
| Field | Nilai Contoh |
|---|---|
| Vault server URL | https://vault.example.com:8200 |
| Vault auth role | gitlab-ci |
Setelah itu, tulis .gitlab-ci.yml dengan id_tokens dan keyword secrets:
deploy:
stage: deploy
image: node:20-alpine
id_tokens:
VAULT_JWT_TOKEN:
aud: https://gitlab.example.com
secrets:
DB_PASSWORD:
vault: kv/data/ci/app DB_PASSWORD@kv
API_KEY:
vault: kv/data/ci/app API_KEY@kv
file: false
script:
- npm run deployAda tiga hal penting yang terjadi di sini:
id_tokens membuat JWT OIDC dengan klaim aud khusus. Runner memakai token ini untuk login ke Vault — tidak ada kredensial long-lived yang disimpan di mana pun.secrets: memberitahu runner: ambil secret ini dari Vault dan jadikan environment variable.vault: adalah vault: <path> <field>@<mount>. Contoh kv/data/ci/app DB_PASSWORD@kv berarti membaca field DB_PASSWORD dari path kv/data/ci/app pada mount kv.Saat job berjalan, DB_PASSWORD dan API_KEY tersedia sebagai environment variable — repository tidak menyimpan secret sama sekali. Rotasi secret cukup dilakukan di Vault, dan seluruh pipeline otomatis memakai nilai baru.
Tip
Untuk secret yang panjang atau berisi karakter aneh, gunakan file: true pada keyword secrets:. Nilai secret ditulis ke file sementara alih-alih environment variable, sehingga mengurangi risiko nilainya ter-print ke log.
.gitlab-ci.yml. File ini ada di repository dan bocor ke siapa pun yang punya akses repo. Gunakan variabel dari UI atau Vault untuk hal sensitif.aud tidak cocok. Jika aud pada id_tokens tidak cocok dengan bound_audiences role Vault, autentikasi gagal dengan error akses ditolak. Pastikan keduanya persis sama.Pada episode 5 ini kalian telah menguasai sistem nilai dalam pipeline:
$CI_COMMIT_SHA, $CI_COMMIT_REF_NAME, $CI_PROJECT_DIR, dan $CI_PIPELINE_ID..gitlab-ci.yml dengan urutan prioritas yang jelas.id_tokens dan keyword secrets untuk secret yang aman, terpusat, dan mudah dirotasi.Sekarang pipeline kalian bisa berbicara, menyimpan konfigurasi, dan menjaga rahasia. Di episode 6 kita akan masuk ke integrasi container — Docker di GitLab CI/CD: menjalankan job dengan custom image, membandingkan Docker-in-Docker vs Kaniko, dan mempublikasikan image ke GitLab Container Registry. Sampai jumpa di episode 6!