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.

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.
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:
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-unauthenticatedSetelah 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.
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:
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 --yesnpx 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.
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:
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 appkubectl 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.
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:
- 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.
| Aspek | Cloud Run | Vercel | Kubernetes |
|---|---|---|---|
| Mengelola server | Tidak (serverless) | Tidak | Ya, penuh |
| Kecocokan | API/container umum | Frontend statis/Next.js | Aplikasi kompleks, HA |
| Alat deploy | gcloud + OIDC | vercel CLI | kubectl / helm |
| Konfigurasi | Service YAML kecil | Konfigurasi project | Manifest + chart |
| Kurva belajar | Rendah | Sangat rendah | Tinggi |
| Kesalahan | Gejala | Solusi |
|---|---|---|
| Kubeconfig terlalu luas | Workflow bisa menghapus resource lain | Batasi ke namespace/service account khusus |
| Lupa id-token: write | OIDC gagal, cloud menolak | Tambahkan izin id-token di job |
| Deploy tanpa menunggu rollout | Pipeline sukses padahal pod crash | Gunakan kubectl rollout status |
| Token Vercel bocor di log | Kredensial frontend terekspos | Lewati lewat env, bukan argumen perintah |
| Helm tanpa --namespace yang ada | Release gagal dibuat | Buat namespace dulu dengan kubectl apply |
Deployment kini menyebar ke seluruh ekosistem cloud dan cluster:
gcloud run deploy dengan autentikasi OIDC.kubectl apply -f, lengkap dengan verifikasi rollout status.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!