Sebelum apply, kode wajib rapi dan teruji. Episode ini membahas perapihan otomatis dengan tofu fmt dan tofu validate, static analysis lewat tflint, Checkov, dan Trivy, serta framework testing native tofu test dengan file .tftest.hcl tanpa Go atau Terratest eksternal.

Di episode 10 sebelumnya kita membahas reusable modules — bagaimana mengemas VPC, database, atau aplikasi lengkap ke dalam "lego block" yang bisa dipanggil ulang dari OpenTofu Registry, repository git, atau path lokal. Modul membuat kode jauh lebih kering, tapi ada satu pertanyaan yang masih menggantung: bagaimana kita tahu kode itu benar, rapi, dan aman sebelum menekan tofu apply? Di dunia nyata, infrastruktur yang dirusak oleh satu baris HCL yang salah tulis jauh lebih sering daripada yang dibayangkan — dan semuanya bisa dicegah oleh lapisan kualitas yang terasa membosankan: formatting, linting, dan testing.
Di episode 11 ini kita akan membangun tiga lapis pengaman yang masuk akal untuk dipasang di repositori IaC produksi. Pertama, merapikan dan memvalidasi kode secara otomatis dengan tofu fmt dan tofu validate. Kedua, static security analysis dengan tflint, Checkov, dan Trivy. Ketiga — bintang tamu utama — framework testing native OpenTofu: tofu test dengan file .tftest.hcl yang memungkinkan kalian menulis assertion tanpa perlu belajar Go atau menyusun Terratest. Mari mulai.
Setiap engineer pasti pernah menghabiskan setengah jam berdebat soal indentasi di code review. Di dunia aplikasi biasa debat itu urusan selera; di IaC, perbedaan gaya antar file membuat diff menjadi berisik, menyulitkan review, dan menyembunyikan perubahan yang sebenarnya penting. tofu fmt menghilangkan masalah ini selamanya: ia menulis ulang file .tf agar sesuai dengan kanon resmi — indentasi dua spasi, alignment tanda =, dan blank line setelah setiap blok.
tofu fmt -recursive menembus subfolder, sehingga seluruh struktur modul ikut dirapikan dalam sekali perintah. Untuk pipeline CI, mode check menjadikannya gerbang yang gagal dengan exit code non-nol ketika ada file yang belum diformat:
# Rapikan seluruh file .tf termasuk di subfolder modul
tofu fmt -recursive
# Mode check untuk CI: gagal jika ada file yang belum diformat
tofu fmt -check -recursive
# Tampilkan diff tanpa menulis ulang file
tofu fmt -diff -recursive
# Validasi sintaks & referensi (wajib setelah tofu init)
tofu init
tofu validatetofu validate memeriksa sintaks HCL, validitas ekspresi, referensi antar resource, dan kesesuaian konfigurasi provider. Ia tidak menyentuh cloud sama sekali sehingga berjalan sangat cepat — itulah kenapa ia menjadi gerbang pertama di pipeline. Satu catatan penting: tofu validate butuh skema provider, jadi selalu jalankan tofu init terlebih dahulu.
Tip
Pasang tofu fmt -check -recursive sebagai pre-commit hook atau langkah pertama pipeline. Dua perintah ini menangkap 80 persen masalah sebelum kode sempat dilihat manusia — murah, cepat, dan otomatis.
fmt dan validate hanya menjawab "apakah kode benar secara sintaks" — bukan "apakah kode aman". Untuk itu kita butuh tiga scanner statis yang saling melengkapi:
tflint — linter yang memahami skema provider secara mendalam. Ia menangkap argumen yang sudah deprecated, nama resource yang salah eja, atau konfigurasi yang tidak didukung oleh versi provider yang dipakai. Sekali waktu jalankan tflint --init untuk mengunduh plugin provider.
Checkov — scanner misconfiguration dari Palo Alto Networks. Ia membaca semantik, bukan sekadar sintaks: bucket S3 yang publik, security group dengan port 22 terbuka ke 0.0.0.0/0, atau disk tanpa enkripsi akan langsung dilaporkan, dan ia keluar dengan exit code 1 ketika ada temuan.
Trivy — trivy config . memindai file IaC terhadap database CVE dan best-practice, dan sekalian mendeteksi rahasia yang bocor di dalam kode. Ia juga bisa memindai image container — satu tool untuk dua domain.
# tflint — linter spesifik provider
tflint --init
tflint
# Checkov — scan misconfiguration, exit 1 jika ada temuan
checkov -d . --compact
# Trivy — scan konfigurasi IaC, hanya level parah
trivy config --severity HIGH,CRITICAL .Note
Static scanner membaca kode, bukan state. Sesuatu yang lolos Checkov dan Trivy belum tentu aman di dunia nyata — kombinasi plan review oleh manusia dan approval gate tetap wajib di produksi.
Sebelum OpenTofu, menguji IaC berarti mengadopsi Terratest: menulis kode Go, mengompilasi binary, mengelola go.mod dan dependensi — beban yang besar untuk sebuah assertion kecil seperti "VPC harus memakai CIDR yang benar". OpenTofu membalik paradigma ini dengan framework testing native berbahasa HCL.
File pengujian bernama *.tftest.hcl ditaruh di samping modul. Test terdiri dari blok run dengan command = plan atau apply, dan satu atau lebih blok assert yang berisi condition plus error_message. OpenTofu membuat state terisolasi untuk setiap test dan membersihkannya secara otomatis setelah selesai:
run "verify_vpc" {
command = apply
assert {
condition = aws_vpc.main.cidr_block == "10.0.0.0/16"
error_message = "VPC harus memakai CIDR 10.0.0.0/16"
}
assert {
condition = aws_vpc.main.enable_dns_hostnames == true
error_message = "DNS hostnames wajib aktif untuk cluster EKS"
}
}Menjalankan test semudah perintah berikut:
# Jalankan seluruh test di direktori modul
tofu test
# Hanya test tertentu, dengan output detail
tofu test -filter=verify_vpc -verboseUntuk pengujian tanpa menyentuh cloud sungguhan, OpenTofu menyediakan mock_provider dan override_resource: resource bisa di-mock sehingga assertion dapat diverifikasi murni dalam mode plan. Fitur inilah yang menggantikan kebutuhan Terratest untuk mayoritas kasus — testing IaC akhirnya bisa ditulis oleh orang yang sama yang menulis HCL, tanpa berpindah bahasa.
| Lapisan | Jenis | Apa yang ditangkap | Bisa di CI |
|---|---|---|---|
tofu fmt | Formatting | Gaya kode tidak konsisten | Ya, mode -check |
tofu validate | Validasi | Error sintaks, referensi, provider | Ya |
| tflint | Linting | Argumen deprecated, typo skema | Ya |
| Checkov | Security scan | Port terbuka, bucket publik, disk polos | Ya |
| Trivy | Security scan | Misconfig, CVE, secret bocor | Ya |
tofu test | Pengujian | Perilaku infrastruktur via assertion | Ya |
Warning
Jalankan tofu test di setiap PR, tetapi batasi command = apply ke environment non-produksi atau provider lokal seperti LocalStack. Test dengan apply akan benar-benar membuat resource di cloud — memastikannya menembak environment yang salah adalah kesalahan paling mahal yang bisa terjadi di CI.
Pada episode 11 ini kita telah memasang tiga lapis pengaman kualitas:
tofu fmt -recursive merapikan seluruh kode dengan satu kanon, dan mode -check menjadikannya gerbang CI.tofu validate memvalidasi sintaks dan referensi sebelum menyentuh cloud.tofu test dengan file .tftest.hcl memberikan assertion native tanpa Go atau Terratest, ditambah mock_provider untuk mode plan murni.Kode yang rapi dan teruji hanyalah fondasi — masalah berikutnya adalah bagaimana mengelola ratusan folder infrastruktur tanpa mengulang-ulang konfigurasi yang sama. Itulah tugas Terragrunt. Di episode 12 selanjutnya kita akan mengintegrasikan OpenTofu dengan Terragrunt: menjalankan binary tofu lewat terragrunt --tofu, dan menyusun arsitektur DRY untuk multi-environment Dev, Staging, dan Prod dengan backend serta provider yang terpusat. Sampai jumpa!