Belajar GitHub Actions - Continuous Deployment (CD) ke Cloud & Kubernetes
Episode 14 of 21

Belajar GitHub Actions - Continuous Deployment (CD) ke Cloud & Kubernetes

Episode ini membahas deployment ke cloud dan Kubernetes secara otomatis dari pipeline: Cloud Run dan Vercel untuk PaaS serverless, lalu deploy manifest ke cluster dengan kubectl serta update release Helm dengan helm upgrade.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Pendahuluan

Di episode 13 kita deploy ke server sendiri via SSH dan Ansible — seperti mengelola rumah sendiri: bebas, tapi semua perawatan ada di tangan kita. Sekarang bayangkan layanan yang mengurus gedung, keamanan, dan perawatannya untuk kita. Itulah Cloud PaaS dan Kubernetes: kita fokus pada aplikasi, platform yang mengurus infrastruktur.

Episode 14 membahas dua jalur besar CD: PaaS/Serverless (Cloud Run, Vercel, AWS Lambda) yang menyembunyikan server sepenuhnya, dan Kubernetes yang memberi kendali penuh dengan kompleksitas yang setara. Dua-duanya bisa dideploy otomatis dari workflow.

Pembahasan Utama

Cloud Run: Serverless di GCP

Cloud Run menjalankan container tanpa perlu mengelola node. Karena ia menerima container image (yang kita bangun di episode 12), alur deploy-nya pendek: bangun image, unggah ke registry, lalu beri tahu Cloud Run untuk memakai versi baru.

Autentikasi memakai OIDC dari episode 10 — tanpa kredensial statis. Proyek GCP, region, dan service name bisa diatur sebagai vars:

Deploy ke Cloud Run memakai OIDC
jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - id: auth
        uses: google-github-actions/auth@v2
        with:
          workload_identity_provider: projects/123456789012/locations/global/workloadIdentityPools/ci-pool/providers/github-provider
          service_account: ci-deploy@devvnull-prod.iam.gserviceaccount.com
      - uses: google-github-actions/setup-gcloud@v2
      - run: gcloud builds submit --tag gcr.io/devvnull-prod/app
      - run: |
          gcloud run deploy app \
            --image gcr.io/devvnull-prod/app \
            --region asia-southeast1 \
            --allow-unauthenticated

Setelah auth berhasil, semua perintah gcloud memakai identitas service account yang dipercaya. gcloud run deploy menciptakan revisi baru dan melakukan traffic shift — proses rollback di Cloud Run tinggal menunjuk revisi lama.

Vercel: Frontend yang Deploy Sendiri

Untuk frontend, Vercel adalah primadona: setiap push ke branch utama bisa langsung menjadi rilis produksi. Autentikasi via token yang dibuat di dashboard Vercel, disimpan sebagai secret bersama identitas project:

Deploy frontend ke Vercel
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
      - run: npm ci
      - name: Deploy ke Vercel
        env:
          VERCEL_TOKEN: ${{ secrets.VERCEL_TOKEN }}
          VERCEL_ORG_ID: ${{ secrets.VERCEL_ORG_ID }}
          VERCEL_PROJECT_ID: ${{ secrets.VERCEL_PROJECT_ID }}
        run: npx vercel --prod --token $VERCEL_TOKEN --yes

npx vercel --prod membangun dan menerbitkan rilis produksi dalam satu perintah. Pola yang sama berlaku untuk platform serupa: AWS Lambda memakai CLI aws (dengan configure-aws-credentials dari episode 10) atau framework SAM, dan Netlify punya perintah netlify deploy --prod dengan token yang setara.

Deploy ke Kubernetes dengan kubectl

Di sisi Kubernetes, kita memegang kendali penuh atas deployment, service, dan autoscaling — dan bertanggung jawab atas semuanya. Langkah pertama di workflow: menyiapkan kubeconfig agar kubectl tahu harus bicara ke cluster mana. Kubeconfig di-encode base64, disimpan sebagai secret, lalu ditulis ke runner:

KubernetesDeploy manifest dengan kubectl
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Siapkan kubeconfig
        env:
          KUBECONFIG_B64: ${{ secrets.KUBECONFIG_BASE64 }}
        run: |
          mkdir -p $HOME/.kube
          echo "$KUBECONFIG_B64" | base64 -d > $HOME/.kube/config
          chmod 600 $HOME/.kube/config
      - name: Pasang kubectl
        run: |
          curl -fsSL -o kubectl \
            https://dl.k8s.io/release/$(curl -fsSL https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl
          chmod +x kubectl
          sudo mv kubectl /usr/local/bin/
      - name: Terapkan manifest
        run: |
          kubectl apply -f k8s/namespace.yaml
          kubectl apply -f k8s/deployment.yaml
          kubectl rollout status deployment/app -n app

kubectl apply bersifat deklaratif: ia menyamakan kondisi cluster dengan apa yang tertulis di manifest — bukan mengeksekusi langkah per langkah. rollout status membuat workflow menunggu deployment benar-benar selesai dan pod sehat sebelum dinyatakan sukses, sehingga deploy yang setengah jadi tidak lolos.

Tip

Batasi kubeconfig pada satu namespace atau satu service account dengan RBAC yang sempit. Kubeconfig produksi berisi kemampuan menghancurkan cluster — jangan berikan ke workflow yang juga jalan pada pull request. Pisahkan kubeconfig per environment, dan batasi secret tersebut ke environment produksi saja.

Helm: Mengemas dan Meng-update Release

Manifest mentah cepat menjadi tidak terkendali seiring tambahan environment dan konfigurasi. Helm mengemas semuanya menjadi chart — template manifest dengan nilai yang bisa di-inject saat deploy. Dari workflow, chart diaplikasikan dengan helm upgrade --install, dan versi image disuntikkan lewat --set:

Update release Helm dari workflow
      - name: Pasang Helm
        run: |
          curl -fsSL https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
      - name: Upgrade release
        run: |
          helm upgrade --install app ./helm/app \
            --namespace app \
            --set image.tag=${{ github.sha }}

helm upgrade --install berarti: install bila belum ada, perbarui bila sudah. Menyuntikkan hash commit sebagai tag image memastikan cluster memakai versi yang sama persis dengan yang baru saja dibangun dan dites di pipeline. Kombinasi kubectl apply dan Helm inilah yang melandasi pola GitOps — cluster mengikuti kondisi yang tersimpan di git.

Memilih Target Deployment

AspekCloud RunVercelKubernetes
Mengelola serverTidak (serverless)TidakYa, penuh
KecocokanAPI/container umumFrontend statis/Next.jsAplikasi kompleks, HA
Alat deploygcloud + OIDCvercel CLIkubectl / helm
KonfigurasiService YAML kecilKonfigurasi projectManifest + chart
Kurva belajarRendahSangat rendahTinggi

Kesalahan Umum

KesalahanGejalaSolusi
Kubeconfig terlalu luasWorkflow bisa menghapus resource lainBatasi ke namespace/service account khusus
Lupa id-token: writeOIDC gagal, cloud menolakTambahkan izin id-token di job
Deploy tanpa menunggu rolloutPipeline sukses padahal pod crashGunakan kubectl rollout status
Token Vercel bocor di logKredensial frontend tereksposLewati lewat env, bukan argumen perintah
Helm tanpa --namespace yang adaRelease gagal dibuatBuat namespace dulu dengan kubectl apply

Penutup

Deployment kini menyebar ke seluruh ekosistem cloud dan cluster:

  • Cloud Run menerima container via gcloud run deploy dengan autentikasi OIDC.
  • Vercel (dan Netlify, Lambda) mendeploy aplikasi frontend/serverless dari satu perintah CLI.
  • Kubernetes menerima manifest lewat kubectl apply -f, lengkap dengan verifikasi rollout status.
  • Helm mengemas manifest menjadi chart yang di-update dengan helm upgrade --install dan image tag dinamis.

Di episode 15 berikutnya, kita berpindah ke lapisan paling dasar dari seluruh pipeline: Setup & Management Self-Hosted Runners — kapan perlu runner sendiri, cara registrasinya di Linux, mengamankannya, hingga autoscaling di Kubernetes dengan Actions Runner Controller. Karena semua pipeline hebat di atas berjalan di atas runner!

Belajar GitHub Actions - Continuous Deployment (CD) ke Cloud & Kubernetes | Belajar GitHub Actions