Membuat platform bisa di-review dan direproduksi: IaC dengan Terraform/OpenTofu untuk provisioning, GitOps dengan ArgoCD/Flux untuk sinkronisasi state cluster, dan policy-as-code sebagai penjaga konfigurasi

Setelah di episode 4 kita membangun struktur Kubernetes yang benar (namespace, quota, RBAC), muncul pertanyaan kritis: siapa yang menjamin struktur itu tetap benar? Manusia tidak bisa dipercaya untuk menekan tombol yang sama dengan sempurna setiap minggu. Jawabannya adalah IaC dan GitOps: ubah seluruh konfigurasi platform menjadi kode yang di-review, diuji, dan disinkronkan otomatis.
Mengapa episode ini adalah tulang punggung platform? Karena hampir semua episode berikutnya — dari Backstage, service mesh, sampai NetworkPolicy — akan memakai mekanisme yang kita bangun di sini. GitOps adalah control loop yang menjaga seluruh platform tetap pada kondisi yang diinginkan. Tanpa GitOps, platform hanyalah kumpulan konfigurasi yang perlahan-lahan melenceng.
Banyak yang mencampuradukkan keduanya. Mari kita pisahkan dengan tegas:
| Aspek | IaC (Terraform/OpenTofu) | GitOps (ArgoCD/Flux) |
|---|---|---|
| Objek yang dikelola | Cloud resource: VPC, cluster, IAM, database | Resource di dalam cluster: Deployment, Service, ConfigMap |
| Mekanisme | Provisioning (create/update/destroy) | Reconciliation (selalu samakan state) |
| Siklus | Plan → Apply → Selesai | Loop terus-menerus memantau drift |
| "Git adalah source of truth" | Repo sebagai input | Repo sebagai satu-satunya sumber kebenaran |
Pembagian tugasnya: OpenTofu menghidupkan infrastruktur (misalnya cluster EKS dan node group), ArgoCD mengelola isi cluster (semua workload dan konfigurasi). Keduanya bekerja sama: IaC menyediakan skeleton, GitOps menjaga daging di atasnya.
Platform engineer mengorganisir IaC menjadi modul yang bisa dipakai ulang. Pola umum:
infra/
├── modules/
│ ├── k8s-cluster/ # modul cluster reusable
│ ├── platform-namespace/ # namespace + quota + limitrange
│ └── team-bootstrap/ # setup awal tim baru
├── environments/
│ ├── dev/main.tf
│ ├── staging/main.tf
│ └── prod/main.tf
└── backend.tf # state remote (S3/GCS)Modul yang paling mencerminkan kerja platform engineer adalah onboarding tim baru — satu modul yang membuat namespace, quota, RBAC, dan base config dalam satu tofu apply:
variable "team_name" {
type = string
description = "Nama tim, misalnya payments"
}
variable "environments" {
type = list(string)
default = ["dev", "prod"]
}
resource "kubernetes_namespace" "team_ns" {
for_each = toset(var.environments)
metadata {
name = "team-${var.team_name}-${each.value}"
labels = {
team = var.team_name
environment = each.value
managed-by = "platform"
}
}
}
resource "kubernetes_resource_quota" "quota" {
for_each = toset(var.environments)
metadata {
name = "team-quota"
namespace = kubernetes_namespace.team_ns[each.value].metadata[0].name
}
spec {
hard = {
"requests.cpu" = "8"
"requests.memory" = "16Gi"
"limits.cpu" = "16"
"limits.memory" = "32Gi"
}
}
}Dengan modul ini, onboarding tim baru yang tadinya butuh tiket dan 2 hari kerja menjadi satu PR yang di-review lalu di-apply dalam hitungan menit. Inilah contoh nyata productize infrastruktur.
Important
State remote wajib. Jangan pernah menyimpan state Terraform hanya di laptop — multi-engineer akan saling menimpa. Gunakan state remote (S3/GCS dengan locking DynamoDB/GCS). backend "s3" di backend.tf bukan saran, melainkan keharusan untuk tim platform.
ArgoCD adalah implementasi GitOps paling populer di ekosistem CNCF. Prinsip kerjanya sederhana: ArgoCD membaca repo, lalu membuat cluster menyerupai repo. Setiap drift (perubahan manual di cluster) akan dideteksi dan dikembalikan.
ArgoCD menyinkronkan "Application" — unit yang menghubungkan repo, target path, dan destination cluster:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: platform-baseline
namespace: argocd
spec:
project: platform
source:
repoURL: https://github.com/org/infra
path: platform-baseline
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=truePerhatikan syncPolicy.automated dengan prune dan selfHeal: ini membuat ArgoCD menghapus resource yang hilang dari repo dan memperbaiki perubahan manual. Ini adalah definisi kerja GitOps yang sesungguhnya — bukan sekadar "deploy dari git".
Di episode 4 kita membangun isolasi namespace; sekarang isolasi itu dilengkapi di level GitOps dengan AppProject yang membatasi tim mana boleh deploy ke namespace mana:
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: team-payments
namespace: argocd
spec:
sourceRepos:
- "https://github.com/org/team-payments-*"
destinations:
- namespace: team-payments-*
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: ""
kind: Namespace
roles:
- name: team-admin
groups:
- team-payments@example.com
policies:
- p, proj:team-payments:team-admin, applications, get, team-payments/*, allow
- p, proj:team-payments:team-admin, applications, sync, team-payments/*, allowArgoCD Project adalah jembatan antara Git dan Kubernetes security: tim hanya bisa sync aplikasi mereka ke namespace mereka.
IaC dan GitOps menjaga apa yang di-deploy; policy-as-code menjaga siapa boleh deploy apa. Alat utamanya adalah Open Policy Agent (OPA) + Gatekeeper atau Kyverno. Prinsipnya: aturan ditulis sebagai kode, dijalankan sebagai admission controller, dan menolak konfigurasi yang melanggar.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-team-labels
spec:
validationFailureAction: Enforce
rules:
- name: require-team-environment
match:
any:
- resources:
kinds: [Namespace]
validate:
message: "Namespace wajib punya label team dan environment"
pattern:
metadata:
labels:
team: "?*"
environment: "?*"Policy ini membuat episode 4 dan 5 jadi lingkaran tertutup: struktur yang benar (label, quota, RBAC) dipaksakan oleh policy — bukan hanya disarankan di dokumentasi. Kita akan memperdalam policy-as-code dan compliance di episode 16.
Selain ArgoCD ada Flux — pendekatan yang lebih "native Kubernetes" dengan Kustomization dan GitRepository sebagai Custom Resources, plus mekanisme notification yang rapi. Perbandingan singkat:
| Kriteria | ArgoCD | Flux |
|---|---|---|
| UI dashboard | Bawaan, lengkap | Minimalis (webhook + CLI) |
| Multi-cluster | Sangat baik (App of Apps) | Baik (Kustomization per cluster) |
| Notifikasi | Berbasis App | Event-based, terintegrasi Slack |
| Kurva belajar | Sedang | Sedang (konsep agak berbeda) |
Pilih salah satu dan konsisten. Keduanya memenuhi definisi GitOps yang sama.
Inti yang harus dibawa pulang:
Di episode 6 selanjutnya kita membangun wajah dari seluruh fondasi ini: Internal Developer Portal dengan Backstage — software catalog, scaffolder, dan plugin yang membuat platform kalian terlihat dan bisa dipakai oleh developer. Dari control loop kita pindah ke experience layer!