Terraform modules yang benar-benar reusable
Pelajaran dari tiga tahun bikin Terraform modules yang salah — dan pattern yang akhirnya stick.
On this page3 sections
Ada satu kebenaran yang bikin aku males nulis soal Terraform: 80% “best practice” yang kamu temukan di blog pertama kali, baru akan kelihatan salah setelah kamu jalanin di production selama enam bulan.
Post ini bukan best practice. Ini cuma “pattern yang akhirnya aku pakai” setelah beberapa kali refactor.
Masalahnya: module yang terlalu pintar
Module pertama yang aku bikin selalu bentuknya begini:
module "vpc" { source = "./modules/vpc"
name = "production" environment = "prod" cidr = "10.0.0.0/16" azs = ["us-east-1a", "us-east-1b", "us-east-1c"] enable_nat = true enable_vpn = false enable_flow_logs = true tags = { Project = "main" }}Kelihatan rapi. Tapi begitu kebutuhan mulai nyeleneh — misalnya “VPC ini butuh 2 NAT tapi cuma untuk private subnet tertentu” — module-nya mulai bloated jadi seperti ini:
enable_nat = truenat_gateway_count = 2nat_gateway_subnets = ["private-a", "private-b"]nat_gateway_eip_allocation = "managed"Setiap edge case jadi variable baru. 6 bulan kemudian, file variables.tf punya 80 variables.
Yang akhirnya aku pakai: module kecil + composition
Alih-alih satu module besar yang mencoba handle semua kasus, aku pecah jadi building blocks yang lebih primitif:
module "vpc" { source = "./modules/vpc-network" cidr = "10.0.0.0/16" azs = var.azs}
module "public_subnets" { source = "./modules/subnets" vpc_id = module.vpc.id cidrs = ["10.0.0.0/20", "10.0.16.0/20"] public = true}
module "nat" { source = "./modules/nat-gateway" subnet_id = module.public_subnets.ids[0]}Lebih verbose. Tapi:
- Setiap module punya satu tanggung jawab.
- Edge case tidak lagi jadi variable — kamu compose ulang dari building block.
- Testing lebih mudah karena scope kecil.
Aturan praktis yang aku pegang
- Module = abstraksi, bukan preset. Kalau isinya cuma
count = var.enable_x ? 1 : 0, mungkin itu resource biasa aja. - Variable > 10 = smell. Waktu module punya lebih dari 10 variables, 90% kemungkinan dia sudah mencoba handle dua use case berbeda.
- Output yang kamu butuhkan hari ini, bukan yang mungkin dibutuhkan besok. YAGNI berlaku di sini juga.
- Versioning itu wajib. Begitu module dipakai di > 1 tempat, tag dia.
source = "git::...?ref=v1.2.3".
Belum sempurna, tapi paling nggak terraform plan tidak lagi jadi lotere.