Struktur Direktori #
Tidak ada aturan baku tentang bagaimana kamu harus mengatur file Terraform — tapi ada konvensi yang diterima luas dan terbukti membantu proyek tetap maintainable seiring bertambahnya kompleksitas. Struktur yang baik membuat kolaborasi lebih mudah, onboarding lebih cepat, dan debugging lebih terarah.
Konvensi Penamaan File #
Terraform membaca semua file .tf dalam satu direktori secara bersamaan — urutan file tidak penting, tapi nama file yang konsisten membantu navigasi.
# Konvensi penamaan file yang diterima luas:
main.tf ← Resource utama proyek
variables.tf ← Deklarasi semua input variable
outputs.tf ← Deklarasi semua output value
providers.tf ← Konfigurasi provider dan versi
versions.tf ← Terraform version constraint (opsional, bisa di providers.tf)
backend.tf ← Konfigurasi remote backend (opsional)
locals.tf ← Local values (jika banyak, pisah ke file sendiri)
Ini bukan aturan Terraform — kamu bisa menamai file apapun. Tapi konvensi ini membuat developer baru langsung tahu di mana harus mencari apa.
Struktur Proyek Kecil #
Untuk proyek dengan satu environment dan resource yang tidak terlalu banyak, satu direktori sudah cukup.
my-infrastructure/
├── main.tf # Resource utama (EC2, VPC, RDS, dll.)
├── variables.tf # Deklarasi variable
├── outputs.tf # Output values
├── providers.tf # Konfigurasi provider
├── terraform.tfvars # Nilai variable (jangan commit jika ada secret)
└── .terraform.lock.hcl # Lock file provider (selalu commit)
# providers.tf
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
# variables.tf
variable "aws_region" {
description = "AWS region untuk deploy resource"
type = string
default = "ap-southeast-1"
}
variable "environment" {
description = "Nama environment (dev, staging, production)"
type = string
}
Struktur Proyek Multi-Environment #
Proyek yang punya beberapa environment (dev, staging, production) membutuhkan struktur yang lebih terorganisir.
my-infrastructure/
├── modules/ # Modul yang bisa di-reuse
│ ├── vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ └── web-server/
│ ├── main.tf
│ ├── variables.tf
│ └── outputs.tf
│
├── environments/
│ ├── dev/
│ │ ├── main.tf # Panggil modul dengan config dev
│ │ ├── variables.tf
│ │ ├── outputs.tf
│ │ ├── providers.tf
│ │ ├── terraform.tfvars # Nilai variable untuk dev
│ │ └── backend.tf # Remote state untuk dev
│ │
│ ├── staging/
│ │ ├── main.tf
│ │ ├── terraform.tfvars # Nilai variable untuk staging
│ │ └── ...
│ │
│ └── production/
│ ├── main.tf
│ ├── terraform.tfvars
│ └── ...
│
└── .terraform.lock.hcl
Dengan struktur ini, setiap environment punya state-nya sendiri dan perubahan di dev tidak mempengaruhi production.
File yang Harus Di-commit dan Yang Tidak #
Ini salah satu hal yang paling sering membingungkan developer baru.
DI-COMMIT ke Git:
✓ *.tf — semua file konfigurasi Terraform
✓ .terraform.lock.hcl — lock file provider (penting untuk reproducibility)
✓ *.tfvars — nilai variable NON-SECRET (misal: environment name, region)
✓ .gitignore — untuk exclude file yang tidak perlu
JANGAN DI-COMMIT:
✗ terraform.tfstate — state file mengandung data sensitif
✗ terraform.tfstate.backup — backup state
✗ *.tfvars — jika mengandung secret (API key, password)
✗ .terraform/ — direktori cache provider (bisa di-regenerate dengan init)
✗ *.tfplan — saved plan file (bisa mengandung sensitive value)
# .gitignore yang direkomendasikan untuk proyek Terraform
# .gitignore
# Local .terraform directories
**/.terraform/*
# .tfstate files
*.tfstate
*.tfstate.*
# Crash log files
crash.log
crash.*.log
# Exclude all .tfvars files, yang might contain sensitive data
*.tfvars
*.tfvars.json
# Override files (local customizations)
override.tf
override.tf.json
*_override.tf
*_override.tf.json
# Lock file TIDAK di-exclude — ini harus di-commit
# !.terraform.lock.hcl
Anti-Pattern yang Harus Dihindari #
# ANTI-PATTERN 1: Semua resource dalam satu file besar
# main.tf dengan 1000+ baris mencakup VPC, EC2, RDS, IAM, dll.
# → Sulit dibaca, sulit di-maintain, konflik merge yang sering
# BENAR: Pisah berdasarkan logical grouping
networking.tf # VPC, subnet, routing
compute.tf # EC2, auto scaling
database.tf # RDS, ElastiCache
iam.tf # Roles, policies
---
# ANTI-PATTERN 2: Hardcode nilai di dalam resource
resource "aws_instance" "web" {
ami = "ami-0abcdef1234567890" # ✗ hardcode
instance_type = "t3.micro" # ✗ hardcode
}
# BENAR: Gunakan variable
resource "aws_instance" "web" {
ami = var.ami_id
instance_type = var.instance_type
}
---
# ANTI-PATTERN 3: Tidak ada struktur untuk multi-environment
# Semua environment dalam satu direktori dengan variable untuk bedakan
# → State tercampur, berbahaya
# BENAR: Direktori terpisah per environment
# environments/dev/, environments/staging/, environments/production/
# Masing-masing dengan state-nya sendiri
Ringkasan #
- Konvensi file:
main.tf,variables.tf,outputs.tf,providers.tf— nama yang konsisten membuat navigasi lebih mudah untuk semua anggota tim.- Pisah berdasarkan logical grouping untuk file yang besar —
networking.tf,compute.tf,database.tflebih baik dari satumain.tfraksasa.- Multi-environment = direktori terpisah — jangan gunakan satu direktori untuk semua environment, state akan tercampur.
- Commit
.terraform.lock.hcl, jangan commit.terraform/dan*.tfstate.- Hati-hati dengan
.tfvars— jika mengandung secret, jangan di-commit. Gunakan environment variable atau secrets manager.- Modul di direktori
modules/untuk konfigurasi yang di-reuse antar environment.