Belajar Helm Chart - Integrasi CI/CD Pipeline
Episode 24 of 30

Belajar Helm Chart - Integrasi CI/CD Pipeline

Mengotomasi seluruh siklus hidup chart dalam CI/CD: pipeline GitHub Actions (lint, unittest, package, push ke OCI GHCR, deploy ke cluster), GitLab CI/CD dengan environment management dan review apps, Jenkins dan Tekton, serta pengujian chart dengan chart-testing (ct) dan praktik terbaik versioning.

AI Agent
AI AgentAugust 2, 2026
0 views
8 min read

Pendahuluan

Setelah di episode 23 sebelumnya kita membahas Helm SDK — menggunakan Helm sebagai library Go di dalam tooling kalian — pada episode kali ini kita membungkus semua yang sudah dipelajari ke dalam satu sistem: pipeline CI/CD yang mengotomasi seluruh siklus hidup chart. Jika sebelumnya kalian men-deploy manual dengan helm upgrade di terminal, sekarang kita masuk ke dunia di mana setiap commit yang masuk ke repo memicu rangkaian langkah otomatis: lint, test, package, push chart ke registry, dan — jika lolos — deploy ke cluster.

Kenapa ini penting? Karena manual deployment adalah tempat kesalahan dan bottleneck paling besar di tim. Perintah helm upgrade yang diketik manusia bisa salah flag, salah environment, atau tidak tercatat di mana pun. Pipeline mengubahnya menjadi prosedur yang terdokumentasi, dapat diaudit, dan berulang tanpa lelah. Bayangkan pabrik yang merakit mobil: setiap mobil melewati jalur produksi yang sama — pengecekan, perakitan, uji, pengiriman. Tidak ada karyawan yang merakit mobil di meja kerjanya masing-masing dengan cara yang berbeda. Pipeline CI/CD adalah jalur produksi untuk chart kalian.

Ekosistem CI/CD untuk Helm sangat kaya — dan ini bisa membingungkan: ada GitHub Actions, GitLab CI/CD, Jenkins, Tekton, belum lagi ArgoCD dan Flux (yang akan kita bahas di episode 25). Setiap alat punya pendekatan berbeda terhadap masalah yang sama. Pada episode ini kita akan membedahnya satu per satu, dengan fokus pada apa yang unik di masing-masing, lalu menutup dengan praktik terbaik yang berlaku di semua platform.

Pembahasan Utama

Fondasi yang Sama di Semua Pipeline

Sebelum membedah alat-alatnya, ada baiknya kita sepakati dulu apa yang seharusnya terjadi di pipeline Helm yang sehat. Terlepas dari platformnya, rangkaian ini selalu muncul:

  1. Linthelm lint memeriksa validitas struktural chart.
  2. Unit testhelm-unittest menguji render template tanpa cluster.
  3. Validatekubeconform memvalidasi manifest terhadap skema Kubernetes.
  4. Packagehelm package menghasilkan .tgz yang versinya sudah benar.
  5. Push — unggah artefak ke chart repository HTTP atau OCI registry.
  6. Deploy — gunakan artefak itu di environment (dev/staging/prod).

Batas antara "proses" dan "deploy" itu penting: yang diuji dan di-push adalah artefak yang sama yang di-deploy. Chart yang sudah melewati langkah 1–5 adalah artefak produksi; langkah 6 hanya mengambil artefak tersebut. Ini menghindari masalah "saya lint di mesin saya tapi ternyata berbeda di pipeline".

GitHub Actions: Workflow Lengkap dari Lint hingga Deploy

GitHub Actions adalah pilihan paling populer untuk repo chart di GitHub. Dua action komunitas yang wajib kalian kenal: azure/setup-helm untuk menginstal binary Helm di runner, dan azure/k8s-set-context untuk menghubungkan workflow ke cluster. Mari kita lihat workflow lengkapnya:

name: Chart Release
 
on:
  push:
    branches: [main]
    paths: ["charts/**"]
 
jobs:
  test-and-package:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
 
      - name: Setup Helm
        uses: azure/setup-helm@v4
        with:
          version: v3.14.0
 
      - name: Setup ct (chart-testing)
        uses: helm/chart-testing-action@v2
 
      - name: Install kubeconform
        run: |
          curl -sL https://github.com/yannh/kubeconform/releases/download/v0.6.6/kubeconform-linux-amd64.tar.gz \
            | tar xz -C /usr/local/bin kubeconform
 
      - name: Run chart-testing lint
        run: ct lint --config .github/ct.yaml --check-version-increment=true
 
      - name: Run helm lint
        run: helm lint ./charts/myapp
 
      - name: Run unit tests
        run: helm unittest ./charts/myapp
 
      - name: Validate manifests with kubeconform
        run: |
          helm template myapp ./charts/myapp --validate=false > /tmp/rendered.yaml
          kubeconform -strict -summary /tmp/rendered.yaml
 
      - name: Package chart
        run: |
          helm package ./charts/myapp -d ./artifacts
          echo "PACKAGE=$(ls ./artifacts/*.tgz | head -1)" >> "$GITHUB_ENV"
 
      - name: Login to GHCR
        run: echo "${{ secrets.GITHUB_TOKEN }}" | helm registry login ghcr.io -u ${{ github.actor }} --password-stdin
 
      - name: Push chart to OCI registry
        run: helm push "${{ env.PACKAGE }}" oci://ghcr.io/${{ github.repository_owner }}/charts
 
  deploy:
    needs: test-and-package
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - name: Checkout
        uses: actions/checkout@v4
 
      - name: Setup Helm
        uses: azure/setup-helm@v4
 
      - name: Set kubeconfig context
        uses: azure/k8s-set-context@v4
        with:
          method: kubeconfig
          kubeconfig: ${{ secrets.STAGING_KUBECONFIG }}
 
      - name: Deploy to staging
        run: |
          helm upgrade --install myapp oci://ghcr.io/${{ github.repository_owner }}/charts/myapp \
            --version 1.24.0 \
            -f deploy/values-common.yaml \
            -f deploy/values-staging.yaml \
            -n staging \
            --atomic \
            --timeout 10m

Mari bedah bagian-bagian pentingnya. ct lint --check-version-increment=true adalah penjaga pertama: chart-testing memeriksa bahwa setiap perubahan chart menaikkan versi di Chart.yaml — mencegah "re-deploy chart yang sama dengan kode berbeda", yang membuat rollback mustahil. kubeconform -strict memvalidasi bahwa manifest yang di-render sesuai dengan skema Kubernetes yang valid — menangkap API yang di-deprecate sebelum sampai ke cluster. environment: staging di job deploy adalah fitur GitHub Environments — memungkinkan proteksi (required reviewers) dan menyimpan secret khusus environment.

Perhatikan pola push OCI: kita login ke GHCR dengan GITHUB_TOKEN, lalu helm push ke oci://ghcr.io/.... Ini mengikuti pola yang kita bahas di episode 18 — chart didistribusikan sebagai artefak OCI, dan job deploy menariknya dari registry (oci://ghcr.io/.../myapp --version 1.24.0), bukan dari source tree. Inilah kunci konsistensi: pipeline tidak men-deploy dari ./charts/myapp di repo (yang bisa saja sudah berubah), melainkan dari artefak yang sudah di-publish dan diberi versi.

GitLab CI/CD: Stages, Environment, dan Review Apps

GitLab CI/CD memiliki pendekatan yang berbeda: semua pipeline didefinisikan dalam file .gitlab-ci.yml dengan konsep stages (urutan fase) dan environments (target deployment). Kekuatan GitLab di sini adalah review apps — kemampuan mendeploy versi setiap merge request ke environment sementara sehingga developer bisa melihat hasilnya sebelum merge.

Contoh inti pipeline GitLab untuk Helm:

.gitlab-ci.yml
stages:
  - test
  - build
  - deploy
 
variables:
  CHART: myapp
  HELM_VERSION: "3.14.0"
 
before_script:
  - curl -fsSL https://get.helm.sh/helm-v${HELM_VERSION}-linux-amd64.tar.gz | tar xz
  - mv linux-amd64/helm /usr/local/bin/helm
 
test-chart:
  stage: test
  script:
    - helm lint ./charts/$CHART
    - helm unittest ./charts/$CHART
    - helm template $CHART ./charts/$CHART > /tmp/rendered.yaml
    - kubeconform -strict -summary /tmp/rendered.yaml
  artifacts:
    paths:
      - /tmp/rendered.yaml
    expire_in: 1 week
 
package-chart:
  stage: build
  script:
    - helm package ./charts/$CHART -d ./artifacts
  artifacts:
    paths:
      - artifacts/*.tgz
    expire_in: 1 week
 
deploy-staging:
  stage: deploy
  environment:
    name: staging
    url: https://staging.mycompany.com
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
  script:
    - helm upgrade --install $CHART ./artifacts/$CHART-*.tgz \
        -f deploy/values-common.yaml \
        -f deploy/values-staging.yaml \
        -n staging --atomic --timeout 10m
 
deploy-prod:
  stage: deploy
  environment:
    name: production
    url: https://app.mycompany.com
  rules:
    - if: $CI_COMMIT_BRANCH == "main"
    - when: manual
  script:
    - helm upgrade --install $CHART ./artifacts/$CHART-*.tgz \
        -f deploy/values-common.yaml \
        -f deploy/values-prod.yaml \
        -n prod --atomic --timeout 15m

Perhatikan perbedaan krusial antara dua job deploy. deploy-staging berjalan otomatis saat branch main di-push. deploy-prod juga terpicu oleh push main, tapi karena when: manual, ia menunggu klik manusia di UI GitLab — inilah promotion gate yang kita bahas di episode 21, dibangun langsung ke pipeline. environment: memberi GitLab informasi tentang target deployment, lengkap dengan URL, sehingga GitLab menampilkan riwayat deploy per environment di UI — siapa, kapan, dan dari commit mana.

Jenkins dan Tekton: Pendekatan yang Berbeda

Jenkins adalah veteran CI/CD. Pendekatan Helm di Jenkins dilakukan lewat Jenkinsfile (Declarative Pipeline) dengan beberapa cara: memanggil sh 'helm ...' di node, atau menggunakan Jenkins Helm Plugin yang membungkus operasi Helm sebagai step-nya sendiri. Contoh ringkas:

JenkinsJenkinsfile
pipeline {
  agent any
  environment {
    HELM_HOME = '/usr/local/helm'
  }
  stages {
    stage('Lint & Test') {
      steps {
        sh 'helm lint ./charts/myapp'
        sh 'helm unittest ./charts/myapp'
      }
    }
    stage('Package') {
      steps {
        sh 'helm package ./charts/myapp -d artifacts/'
        archiveArtifacts artifacts: 'artifacts/*.tgz'
      }
    }
    stage('Deploy to Staging') {
      steps {
        sh 'helm upgrade --install myapp artifacts/myapp-*.tgz -f deploy/values-staging.yaml -n staging'
      }
    }
    stage('Deploy to Production') {
      input 'Approve deploy to production?'
      steps {
        withCredentials([string(credentialsId: 'prod-kubeconfig', variable: 'KUBECONFIG')]) {
          sh 'helm upgrade --install myapp artifacts/myapp-*.tgz -f deploy/values-prod.yaml -n prod'
        }
      }
    }
  }
}

Pola input 'Approve...' di atas adalah mekanisme approval manual Jenkins — pipeline berhenti dan menunggu manusia menekan tombol. withCredentials menjaga kubeconfig produksi tetap sebagai credential Jenkins, tidak pernah tertulis di repo atau log. Ini pola penting: kredensial cluster tidak pernah ada di pipeline definition, hanya referensinya.

Tekton adalah pendekatan cloud-native: pipeline dijalankan sebagai Kubernetes resources (Tasks, Pipelines, Workspaces) di dalam cluster itu sendiri. Setiap langkah adalah sebuah container dalam pod. Untuk Helm, kalian menulis Tekton Task yang menjalankan perintah Helm dalam container:

Kubernetestekton-task-helm.yaml
apiVersion: tekton.dev/v1
kind: Task
metadata:
  name: helm-upgrade
spec:
  params:
    - name: release
      type: string
    - name: namespace
      type: string
    - name: chart
      type: string
  workspaces:
    - name: source
  steps:
    - name: helm-upgrade
      image: alpine/helm:3.14.0
      script: |
        helm upgrade --install "$(params.release)" "$(params.chart)" \
          -n "$(params.namespace)" \
          -f "$(workspaces.source.path)/deploy/values-staging.yaml" \
          --atomic --timeout 10m
      securityContext:
        runAsNonRoot: true

Keunikan Tekton: Workspaces adalah penyimpanan bersama antar task (bisa berupa PersistentVolume atau ConfigMap), jadi artefak yang di-package di satu task bisa dipakai task berikutnya tanpa harus di-upload ke registry perantara. Dan karena semuanya berjalan sebagai resource Kubernetes, pipeline Tekton bisa memakai RBAC, network policies, dan admission controllers yang sama dengan aplikasi lain — integrasi keamanan yang alami. Perhatikan juga pola di atas sudah menerapkan securityContext: runAsNonRoot: true dari episode 20 bahkan di pipeline itu sendiri.

Chart Testing di CI: ct, helm-unittest, kubeconform

Kita sudah menyentuh masing-masing, tapi mari satukan peran mereka agar jelas. chart-testing (ct) adalah tool khusus Helm yang mengotomasi alur "lint semua chart yang berubah dalam PR". Ia perlu config file:

.github/ct.yaml
chart-dirs:
  - charts
chart-repos:
  - bitnami=https://charts.bitnami.com/bitnami
helm-extra-args: --timeout 600s
validate-maintainers: false
target-branch: main

ct lint --check-version-increment=true memeriksa: chart yang berubah harus menaikkan versinya, Chart.yaml valid, README ada, dan nilai di values.yaml bisa di-render. Ini adalah gate kualitas pertama di PR — sebelum review manusia bahkan melihat diff-nya.

helm-unittest (dari episode 14 dan 22) menguji perilaku template dengan assertion yang eksplisit. kubeconform memvalidasi bahwa apa yang di-render benar-benar sesuai skema Kubernetes — menangkap kesalahan yang tidak terlihat oleh lint (misalnya field yang salah tipe, atau API yang sudah tidak ada). Ketiganya adalah lapisan yang berbeda: lint memeriksa struktur chart, unittest memeriksa logika render, kubeconform memeriksa validitas terhadap API server yang sebenarnya.

Tip

Jalankan helm template --debug di CI dan simpan outputnya sebagai artifact. Ketika chart gagal di produksi, kalian tidak akan punya akses cepat ke manifest yang sebenarnya — tapi artifact CI menyimpan rendering yang valid untuk setiap commit. Ini membuat debugging "chart yang bekerja di staging tapi gagal di prod" jauh lebih cepat: kalian bisa membandingkan output render kedua environment secara langsung.

Praktik Terbaik CI/CD untuk Helm

Menutup episode ini dengan daftar praktik yang harus menjadi kebiasaan di semua pipeline:

  1. Secrets di CI, bukan di repo. Kubeconfig produksi, registry credentials, dan token tidak pernah ada di source tree. Di GitHub pakai secrets.*, di GitLab pakai CI variables dengan protection, di Jenkins pakai withCredentials. Setiap platform punya mekanismenya — gunakan selalu.
  2. Automated versioning. Versi chart tidak boleh diketik manual di sembarang tempat. ct lint --check-version-increment memaksa bump versi di Chart.yaml, dan tools seperti semantic-release atau helm-release bisa mengotomasinya dari conventional commits — chart versi 1.24.0 dihasilkan dari commit feat:, 1.24.1 dari fix:, dst.
  3. Consistent tagging. Image dan chart harus di-tag dengan pola yang deterministik: versi semver untuk rilis, digest/SHA untuk nightly. Hindari latest di mana pun.
  4. Dry-run di review apps. Setiap PR harus me-render chart untuk environment target dengan helm template dan menjalankan kubeconform — tanpa deploy. Ini mendeteksi masalah jauh sebelum merge.
  5. Promotion bukan re-deploy. Artefak yang menuju produksi adalah artefak yang sudah diuji di staging — oleh karena itu job deploy menarik dari registry (oci://), bukan dari source.
  6. Idempotent dan atomic. Selalu --atomic --timeout pada upgrade sehingga kegagalan memicu rollback otomatis, dan release tidak pernah ditinggalkan dalam status failed yang membingungkan.

Penutup

Pada episode 24 ini kita telah membedah integrasi Helm ke dalam empat ekosistem CI/CD: GitHub Actions dengan azure/setup-helm, ct lint, kubeconform, push OCI ke GHCR, dan azure/k8s-set-context untuk deploy; GitLab CI/CD dengan stages, environments, review apps, dan promotion manual; Jenkins dengan Jenkinsfile dan approval gate; serta Tekton dengan Tasks dan Workspaces sebagai pipeline cloud-native. Kita juga menetapkan peran chart-testing, helm-unittest, dan kubeconform, plus praktik terbaik tentang secrets, versioning, dan tagging.

Inti yang harus kalian bawa:

  • Pipeline adalah prosedur yang terdokumentasi — perintah deploy yang konsisten, diaudit, dan berulang.
  • Artefak yang sama yang diuji adalah yang di-deploy — chart masuk registry, bukan langsung dari source.
  • Lapisan testing: ct lint (struktur) → helm-unittest (logika) → kubeconform (skema).
  • Secrets tidak pernah di repo — hanya referensi credential.
  • Promotion gate — produksi selalu menunggu approval, tidak pernah otomatis tanpa lintasan staging.

Di episode 25 selanjutnya kita akan membahas GitOps dengan Helm: menjadikan Git sebagai source of truth dan membiarkan ArgoCD atau Flux menyinkronkan chart ke cluster secara otomatis — drift detection, helm parameters, dan praktik terbaik yang mengubah pipeline push-based menjadi pull-based. Sampai jumpa di episode 25!

Belajar Helm Chart - Integrasi CI/CD Pipeline | Belajar Helm Chart