Mengelola seluruh infrastruktur secara deklaratif: mengintegrasikan Terraform dan Flux melalui provider resmi, bootstrap klaster via Terraform, memahami lapisan-lapisan infrastruktur, serta GitOps untuk infrastruktur dengan Crossplane, Terraform Controller, dan Atlantis menuju full-stack GitOps.

Di episode 28 kalian sudah menguji segala sesuatu di dalam klaster: manifest divalidasi, perubahan diuji dengan dry-run, preview environment bekerja, dan chaos engineering membuktikan ketahanan. Namun ada satu ironi yang tidak bisa disembunyikan: klaster itu sendiri dibuat bagaimana? Selama infrastruktur masih dibuat dengan klik-klik di console cloud atau perintah manual, GitOps hanya setengah selesai.
Ini masalah yang nyata. Aplikasi di dalam klaster bersifat deklaratif dan bisa direproduksi dari Git, tetapi VPC, klaster, dan platform di bawahnya mungkin masih berubah-ubah. Jika kita jujur terhadap prinsip GitOps — desired state disimpan di Git, dan sistem berjalan menuju state itu — maka infrastruktur harus masuk ke dalam mekanisme yang sama. Di sinilah Terraform dan integrasinya dengan Flux berperan.
Pada episode ini kita akan menutup celah tersebut: Terraform bersama Flux dengan provider resmi dan bootstrap via Terraform, lapisan-lapisan infrastruktur dari jaringan sampai aplikasi, GitOps untuk infrastruktur dengan Crossplane, Terraform Controller, dan Atlantis, serta gambaran full-stack GitOps di mana seluruh tumpukan hidup di Git.
Terraform adalah tool IaC paling mapan: ia mendeklarasikan state infrastruktur yang diinginkan dan melakukan plan serta apply untuk mencapai state tersebut. Cakupan Terraform yang umum di dunia Flux:
Dengan Terraform, klaster bisa dihancurkan dan dibangun ulang secara konsisten — fondasi sempurna untuk disaster recovery di episode 26.
Flux memiliki provider Terraform resmi yang memungkinkan instalasi dan bootstrap Flux dilakukan langsung dari Terraform. Provider ini perlu konfigurasi akses Kubernetes dan konfigurasi Git untuk bootstrap:
provider "flux" {
kubernetes = {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
token = data.aws_eks_cluster_auth.this.token
}
git = {
url = "https://github.com/devvnull/gitops-production.git"
branch = "main"
http = {
username = "gitops-bot"
password = var.github_token
}
}
}Provider Flux membaca konfigurasi koneksi klaster dari provider Kubernetes yang sudah ada, sehingga tidak perlu kredensial duplikat.
Dengan provider Flux, bootstrap yang selama ini dilakukan lewat CLI bisa di-deklarasikan sebagai resource Terraform:
resource "flux_bootstrap_git" "this" {
path = "clusters/production"
version = "v2.3.0"
components_extra = ["image-reflector-controller", "image-automation-controller"]
}Saat terraform apply dijalankan, Terraform menginstal controller Flux ke klaster dan menulis Kustomization bootstrap ke repository Git. Kredensial GitHub dikirim melalui variabel, bukan disimpan dalam kode. Hasilnya: terraform apply menghasilkan klaster dengan Flux terpasang dan repository GitOps berisi konfigurasi bootstrap.
Important
Karena Terraform menyimpan state (termasuk kredensial dalam beberapa kasus) di file tfstate, simpan state di backend remote — misalnya S3 dengan bucket terenkripsi — bukan di lokal. State Terraform adalah aset yang harus dijaga seaman konfigurasi itu sendiri.
State Terraform mencatat sumber daya yang dikelola — sumber kebenaran operasional untuk apa yang sudah dibuat. Praktik yang sehat:
State yang dikelola dengan baik membuat terraform plan akurat dan terraform destroy aman.
Infrastruktur yang baik dibangun berlapis, dan setiap lapisan punya alasan tersendiri untuk dikelola secara deklaratif. Lapisan paling dasar adalah jaringan: VPC, subnet, route table, security group, dan gateway. Lapisan ini jarang berubah dan berdampak besar jika salah — justru alasan mengapa ia paling cocok untuk IaC yang ketat.
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
}
resource "aws_subnet" "private_a" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-southeast-1a"
}Lapisan berikutnya adalah klaster itu sendiri. Terraform provision klaster menggunakan provider cloud masing-masing — eks untuk AWS, gke untuk Google Cloud, azurerm untuk Azure — atau provider generic seperti hcloud untuk k3s. Output dari lapisan ini (endpoint, kredensial) menjadi input bagi lapisan platform.
module "eks" {
source = "terraform-aws-modules/eks/aws"
cluster_name = "production"
cluster_version = "1.30"
vpc_id = aws_vpc.main.id
subnet_ids = [aws_subnet.private_a.id, aws_subnet.private_b.id]
enable_irsa = true
}Lapisan platform berisi apa yang berjalan di atas klaster: Flux itu sendiri, operator ingress, cert-manager, monitoring, dan komponen bersama lainnya. Sebagian dikelola oleh Terraform (misal Flux melalui provider), sebagian lagi oleh Flux melalui Kustomization di repository GitOps. Di sinilah dua aliran bertemu: Terraform memastikan komponen inti terpasang, Flux menjaga konfigurasinya sinkron dengan Git.
Lapisan teratas adalah aplikasi — sepenuhnya domain GitOps. Manifest aplikasi, HelmRelease, dan Kustomization aplikasi hidup di repository GitOps dan dikelola oleh Flux tanpa keterlibatan Terraform. Pembagian ini penting: Terraform menangani apa yang jarang berubah, Flux menangani apa yang terus berubah. Masing-masing memakai tool yang paling cocok untuk siklus hidupnya.
| Lapisan | Tool | Frekuensi perubahan |
|---|---|---|
| Jaringan | Terraform | Sangat jarang |
| Klaster | Terraform | Jarang |
| Platform | Terraform + Flux | Kadang |
| Aplikasi | Flux saja | Sering |
Setelah aplikasi masuk Git, muncul pertanyaan berikutnya: bisakah infrastruktur ikut masuk Git dan di-reconcile oleh kontroller seperti Flux? Crossplane menjawabnya dengan mengubah infrastruktur cloud menjadi resource Kubernetes. Crossplane berjalan di dalam klaster, dan dengan provider seperti provider-aws, ia dapat membuat VPC atau database langsung dari manifest:
apiVersion: rds.aws.upbound.io/v1beta1
kind: Instance
metadata:
name: checkout-db
namespace: apps
spec:
forProvider:
dbInstanceClass: db.t3.medium
engine: postgres
allocatedStorage: 20
providerConfigRef:
name: defaultKarena Crossplane resources adalah objek Kubernetes biasa, Flux bisa mengelolanya seperti resource lain — infrastruktur kini benar-benar hidup di Git dan ikut dalam pull-request dan review.
Tip
Crossplane dan Flux saling melengkapi: Flux menjaga Crossplane (dan policy-nya) tetap terpasang, sementara Crossplane menciptakan resource cloud yang dideklarasikan di repository GitOps. Gabungan keduanya membuat seluruh infrastruktur menjadi satu alur kerja GitOps.
Alternatif lain untuk mengelola Terraform melalui GitOps adalah Terraform Controller (tf-controller). Ia menjalankan Terraform di dalam klaster sebagai respons terhadap manifest, mirip cara Flux menjalankan Kustomize. Contoh:
apiVersion: infra.contrib.fluxcd.io/v1alpha2
kind: Terraform
metadata:
name: checkout-db
namespace: apps
spec:
path: ./terraform/checkout-db
interval: 1h
sourceRef:
kind: GitRepository
name: apps
approvePlan: auto
writeOutputsToSecret:
name: checkout-db-outputsDengan tf-controller, perubahan Terraform juga mengalir melalui Git dan PR, menjalankan plan otomatis, dan apply setelah disetujui. Siklus hidup Terraform (drift detection, destroy) dijalankan secara terus-menerus oleh kontroller, bukan hanya saat terraform apply manual.
Atlantis mengambil pendekatan berbeda: ia mengotomasi alur review Terraform berbasis pull request. Ketika sebuah PR mengubah kode Terraform, Atlantis menjalankan terraform plan dan memposting hasilnya sebagai komentar di PR. Setelah disetujui, komentar /apply memicu terraform apply. Atlanis menjaga dua hal sekaligus: semua perubahan lewat review dan state Terraform selalu sinkron dengan PR.
Pola yang umum adalah menggabungkan ketiganya:
Full-stack GitOps berarti tidak ada lapisan yang tersisa di luar Git. Dimulai dari infrastruktur: VPC, klaster, dan layanan cloud dikelola dari repository Git (lewat Terraform di bawah Atlantis atau Crossplane), melalui pull request dengan plan yang otomatis.
Lapisan platform — Flux, operator, ingress, monitoring — di-deklarasi di repository GitOps sebagai Kustomization atau HelmRelease. Tim platform mengubah stack bersama melalui PR, dan Flux menerapkannya dengan mekanisme reconciliation yang sama dengan aplikasi.
Lapisan aplikasi sudah sejak awal berada di Git: manifest, image, dan konfigurasi aplikasi di-deploy oleh Flux. Pipeline CI (episode 27) hanya menulis image dan manifest; semuanya mengalir lewat Git.
Ketika semua lapisan hidup di Git, seluruh organisasi memakai satu alur kerja yang sama:
Tip
Mulai full-stack GitOps dari aplikasi, lalu perluas ke platform, dan terakhir ke infrastruktur — sesuai tingkat kesulitan. Setiap lapisan yang masuk Git mengurangi pengetahuan yang hanya ada di kepala satu orang dan meningkatkan kepercayaan untuk perubahan yang cepat.
Pada episode 29 ini kalian telah menyatukan seluruh tumpukan dalam satu mekanisme: Terraform dan Flux melalui provider resmi dan bootstrap via Terraform, manajemen state yang sehat dengan backend remote, lapisan infrastruktur dari jaringan hingga aplikasi dengan pembagian tool yang tepat, GitOps untuk infrastruktur lewat Crossplane, Terraform Controller, dan Atlantis, serta visi full-stack GitOps dengan workflow terpadu dari pull request sampai eksekusi otomatis.
Inti yang harus dibawa pulang:
terraform apply, bukan langkah manual.Dengan ini, hampir seluruh perjalanan GitOps kalian lengkap. Di episode 30 selanjutnya kita akan membahas Cloud Provider Patterns — menerapkan semua konsep di atas pada penyedia cloud nyata: bootstrap Flux di EKS, GKE, dan AKS, pola multi-region, serta integrasi dengan layanan terkelola dan autentikasi cloud-native. Pastikan tetap semangat!