Kapan Digunakan? #
Terraform bukan solusi universal untuk semua masalah infrastruktur. Ada skenario di mana Terraform adalah pilihan terbaik yang bisa kamu ambil, ada skenario di mana tool lain jauh lebih tepat, dan ada skenario di mana memaksakan Terraform justru menambah kompleksitas yang tidak perlu. Memahami batas ini penting agar kamu tidak over-engineer solusi untuk masalah yang sebenarnya sederhana, atau sebaliknya — under-invest di infrastruktur yang sudah mulai kritis.
Artikel ini membahas secara mendalam kapan dan mengapa kamu harus menggunakan Terraform, kapan sebaiknya memilih alternatif, bagaimana ukuran tim mempengaruhi keputusan, dan bagaimana Terraform berintegrasi dengan ekosistem tool DevOps yang lebih luas.
Decision Framework: Gunakan atau Tidak? #
Keputusan untuk menggunakan Terraform seharusnya didasarkan pada kebutuhan spesifik, bukan hype. Berikut framework keputusan yang bisa kamu gunakan untuk mengevaluasi apakah Terraform tepat untuk kasus kamu.
flowchart TD
A["Apakah kamu mengelola\ninfrastruktur cloud?"] -->|"Tidak"| B["Terraform TIDAK\ndibutuhkan"]
A -->|"Ya"| C["Berapa banyak\nresource yang dikelola?"]
C -->|"< 5 resource"| D["Script/CLI\nmungkin cukup"]
C -->|"5-50 resource"| E["Terraform sangat\nmembantu"]
C -->|"> 50 resource"| F["Terraform\nsangat KRITIS"]
E --> G["Perlu diulang di\nbeberapa environment?"]
F --> G
G -->|"Ya"| H["Terraform\nSANGAT TEPAT"]
G -->|"Tidak"| I["Tetap bermanfaat\nuntuk audit & plan"]
D --> J["Tim hanya 1 orang?"]
J -->|"Ya"| K["CLI manual\nbisa diterima"]
J -->|"Tidak"| L["Pertimbangkan\nTerraform untuk\nkonsistensi"]
style H fill:#e8f5e9,stroke:#2e7d32
style F fill:#e8f5e9,stroke:#2e7d32
style B fill:#f5f5f5,stroke:#9e9e9e
style D fill:#fff3e0,stroke:#e65100
style K fill:#fff3e0,stroke:#e65100Framework di atas bukan aturan keras — lebih seperti panduan umum. Ada skenario di mana bahkan 3 resource pun lebih baik dikelola Terraform (misalnya kalau resource itu kritis dan perlu bisa di-recreate dengan cepat). Ada juga skenario di mana 100 resource bisa dikelola dengan tool lain (misalnya kalau semua resource berada di satu AWS account dan dikelola oleh satu orang).
Skenario di Mana Terraform Paling Tepat #
Ada beberapa skenario di mana Terraform memberikan nilai paling besar dibanding alternatif:
1. Multi-Cloud Infrastructure #
Ketika infrastruktur kamu tersebar di beberapa cloud provider, Terraform menjadi pilihan yang hampir tidak tergantikan. Kamu bisa mengelola resource AWS, GCP, Azure, dan bahkan SaaS (Datadog, PagerDuty, GitHub) dalam satu workflow yang konsisten.
# Multi-cloud: AWS + GCP dalam satu konfigurasi
provider "aws" {
region = "ap-southeast-1"
}
provider "google" {
project = "my-gcp-project"
region = "asia-southeast1"
}
# Web server di AWS
resource "aws_instance" "web" {
ami = "ami-0abcdef1234567890"
instance_type = "t3.medium"
tags = { Name = "web-aws" }
}
# BigQuery dataset di GCP (untuk analytics)
resource "google_bigquery_dataset" "analytics" {
dataset_id = "web_analytics"
location = "asia-southeast1"
}
# DNS di Cloudflare (SaaS)
resource "cloudflare_record" "web" {
zone_id = var.cloudflare_zone_id
name = "app"
value = aws_instance.web.public_ip
type = "A"
}
# Monitoring di Datadog (SaaS)
resource "datadog_monitor" "web_health" {
name = "Web Server Health"
type = "service check"
message = "Web server is down! Notify @pagerduty"
query = "process.up('web-server').last(2).count_by_status()"
}
Bayangkan harus menggunakan CloudFormation untuk AWS, Deployment Manager untuk GCP, dan masing-masing provider CLI untuk Cloudflare dan Datadog. Empat tool berbeda dengan empat workflow berbeda — dibanding satu terraform apply.
2. Infrastructure yang Perlu Direproduksi #
Ketika kamu perlu membuat environment yang identik (staging = production, atau region baru = region lama), Terraform sangat tepat. Cukup jalankan konfigurasi yang sama dengan parameter yang berbeda.
# module-environment/main.tf — Module yang bisa dipakai untuk
# membuat environment yang identik
module "staging" {
source = "./modules/web-stack"
environment = "staging"
instance_type = "t3.small"
instance_count = 1
db_instance = "db.t3.medium"
db_multi_az = false
}
module "production" {
source = "./modules/web-stack"
environment = "production"
instance_type = "t3.large"
instance_count = 3
db_instance = "db.r5.large"
db_multi_az = true
}
Kedua environment dibuat dari module yang sama. Kalau staging berfungsi dengan baik, production juga akan berfungsi — karena kode yang menghasilkan infrastrukturnya identik.
3. Tim dengan Beberapa Engineer #
Ketika lebih dari satu orang mengelola infrastruktur, konsistensi menjadi masalah kritis. Dengan Terraform, semua orang menggunakan kode yang sama, review dilakukan di Pull Request, dan perubahan tercatat di Git.
flowchart LR
subgraph Solo["Solo Developer"]
S1["1 Orang, 1 Console"] --> S2["Cukup dengan\nCLI manual"]
end
subgraph Team["Tim 2-5 Orang"]
T1["Beberapa Orang\nAkses Sama"] --> T2["Perlu Konsistensi"]
T2 --> T3["Terraform\n+ Git Workflow"]
end
subgraph Large["Tim Besar 5+"]
L1["Banyak Orang\nBanyak Service"] --> L2["Perlu Standarisasi"]
L2 --> L3["Terraform\n+ Modules\n+ CI/CD Pipeline"]
end
Solo --> S3["⚠️ Risiko: single\npoint of failure"]
Team --> T4["✓ Audit trail\n✓ Code review"]
Large --> L5["✓ Self-service\n✓ Governance\n✓ Compliance"]
style S3 fill:#ffebee,stroke:#c62828
style T4 fill:#e8f5e9,stroke:#2e7d32
style L5 fill:#e8f5e9,stroke:#2e7d324. Compliance dan Audit Requirements #
Ketika organisasi kamu harus memenuhi standar compliance (SOC2, ISO 27001, PCI-DSS), kemampuan untuk membuktikan siapa yang mengubah apa, kapan, dan mengapa adalah keharusan. Git + Terraform menyediakan audit trail yang lengkap.
# Auditor bertanya: "Siapa yang membuka port 22 ke publik?"
# Jawaban ada di git log:
$ git log --oneline security-groups.tf
f4a5b6c Tutup port 22 dari publik — remediasi audit (#198)
a1b2c3d Buka port 22 untuk troubleshooting sementara (#189)
# Bisa ditelusuri: siapa (git author), kapan (timestamp),
# mengapa (commit message + PR description)
5. Disaster Recovery dan Business Continuity #
Ketika infrastruktur kamu didefinisikan dalam kode, disaster recovery berubah dari “rekonstruksi manual berhari-hari” menjadi “jalankan terraform apply di region baru dalam hitungan menit.”
# Ubah satu variabel untuk failover ke region lain
variable "aws_region" {
description = "AWS region untuk deployment"
type = string
default = "ap-southeast-1" # Ubah ke ap-northeast-1 untuk DR
}
provider "aws" {
region = var.aws_region
}
# Seluruh infrastruktur akan dibuat di region baru
# dengan konfigurasi yang identik
Skenario di Mana Terraform TIDAK Tepat #
Sama pentingnya dengan mengetahui kapan menggunakan Terraform, kamu juga harus tahu kapan tidak menggunakannya.
1. Konfigurasi Server (Configuration Management) #
Terraform punya provisioner seperti remote-exec dan file untuk mengkonfigurasi server, tapi ini bukan kekuatannya. Ansible, Chef, atau Puppet jauh lebih tepat untuk tugas ini.
// ANTI-PATTERN: Menggunakan Terraform remote-exec untuk konfigurasi server
resource "aws_instance" "web" {
ami = "ami-0abcdef1234567890"
instance_type = "t3.medium"
// JANGAN LAKUKAN INI:
provisioner "remote-exec" {
inline = [
"sudo apt-get update",
"sudo apt-get install -y nginx",
"sudo systemctl start nginx",
"sudo systemctl enable nginx",
// ... 50 baris lagi konfigurasi
// Tidak idempotent, tidak ada rollback
// Error handling sangat terbatas
]
}
}
// BENAR: Gunakan Terraform untuk provisioning,
// Ansible untuk konfigurasi
resource "aws_instance" "web" {
ami = "ami-0abcdef1234567890"
instance_type = "t3.medium"
tags = { Name = "web-server" }
}
// Lalu jalankan Ansible playbook terpisah
// untuk mengkonfigurasi server
2. Deployment Aplikasi #
Deploy aplikasi (build, test, push image, update service) adalah proses CI/CD yang lebih tepat ditangani oleh tool seperti GitHub Actions, GitLab CI, atau Jenkins.
# BENAR: Deployment ditangani oleh CI/CD pipeline
# (GitHub Actions example)
name: Deploy Application
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build and push Docker image
run: |
docker build -t app:${{ github.sha }} .
docker push registry.com/app:${{ github.sha }}
- name: Update Kubernetes deployment
run: |
kubectl set image deployment/app \
app=registry.com/app:${{ github.sha }}
3. Infrastruktur yang Sangat Sederhana #
Kalau kamu hanya punya 1-2 resource dan tidak ada rencana untuk berkembang, overhead menulis dan memelihara Terraform config mungkin tidak sebanding dengan manfaatnya.
KAPAN CLI MANUAL MASIH BISA DITERIMA:
✓ Hanya 1-2 resource (misalnya 1 VPS + 1 domain)
✓ Tidak perlu diulang di environment lain
✓ Dikelola oleh 1 orang
✓ Tidak ada compliance requirement
✓ Prototype / side project / hackathon
KAPAN SEGERA BERALIH KE TERRAFORM:
✗ Mulai butuh environment kedua (staging)
✗ Tim bertambah orang
✗ Resource bertambah > 5
✗ Mulai ada compliance requirement
✗ Ingin bisa disaster recovery
4. Orchestration Container Murni #
Jika seluruh workload kamu berjalan di Kubernetes dan kamu tidak mengelola cluster itu sendiri (managed Kubernetes), tool seperti Helm, Kustomize, atau ArgoCD mungkin lebih tepat.
// ANTI-PATTERN: Menggunakan Terraform untuk deploy ke K8s
// yang sudah ada
resource "kubernetes_deployment" "app" {
metadata {
name = "my-app"
}
spec {
replicas = 3
// ... definisi deployment lengkap
}
}
// Masalah: terraform plan selalu menunjukkan perubahan
// karena K8s controller mengubah desired state
// Lebih baik gunakan Helm atau Kustomize untuk K8s workload
Pertimbangan Skala Tim #
Ukuran tim sangat mempengaruhi bagaimana kamu menggunakan Terraform — bukan hanya apakah kamu menggunakannya, tapi bagaimana workflow-nya.
Solo Developer #
Seorang solo developer bisa menggunakan Terraform dengan cara paling sederhana: satu direktori, satu state file, langsung terraform apply dari laptop.
# Workflow solo developer
$ terraform init
$ terraform plan
$ terraform apply
# Cukup sederhana, tidak perlu CI/CD pipeline
# State di local atau S3
Namun, bahkan untuk solo developer, ada manfaat besar: kemampuan untuk menghancurkan dan membuat ulang seluruh infrastruktur dengan satu perintah. Ini sangat berguna untuk eksperimen, testing, dan disaster recovery.
Tim Kecil (2-5 Orang) #
Tim kecil memerlukan koordinasi yang lebih baik. Terraform + Git + Remote State adalah kombinasi minimum.
WORKFLOW TIM KECIL:
1. Engineer A membuat branch "add-monitoring"
2. Engineer A menambah resource monitoring di Terraform
3. Engineer A menjalankan terraform plan di local
4. Engineer A membuat Pull Request dengan output plan
5. Engineer B review PR + plan
6. Merge → CI/CD menjalankan terraform apply
KEBUTUHAN MINIMUM:
✓ Remote state (S3 + DynamoDB locking)
✓ Git repository untuk konfigurasi
✓ Pull Request review process
✓ terraform plan di PR (CI/CD atau manual)
Tim Menengah (5-15 Orang) #
Tim menengah memerlukan standarisasi yang lebih kuat — module bersama, naming convention, dan kemungkinan Terragrunt untuk DRY configuration.
// terragrunt.hcl — DRY configuration untuk multi-environment
remote_state {
backend = "s3"
generate = {
path = "backend.tf"
if_exists = "overwrite"
}
config = {
bucket = "company-terraform-state"
key = "${path_relative_to_include()}/terraform.tfstate"
region = "ap-southeast-1"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
terraform {
source = "../../modules//web-stack"
}
Tim Besar (15+ Orang) #
Tim besar memerlukan platform team yang dedicated untuk mengelola Terraform — membuat module, mengatur policy, dan menyediakan self-service untuk developer.
flowchart TD
subgraph Platform["Platform Team"]
P1["Maintain Terraform\nModules"]
P2["Set Policy\n(OPA/Sentinel)"]
P3["Manage CI/CD\nPipeline"]
P4["Provide\nSelf-Service"]
end
subgraph Dev["Developer Teams"]
D1["Team A:\nWeb Application"]
D2["Team B:\nData Pipeline"]
D3["Team C:\nMobile Backend"]
end
Platform -->|"Module + Policy"| Dev
Dev -->|"PR + terraform plan"| Platform
D1 --> S1["Gunakan module:\nmodule \"web\" {\n source = \"company/web/aws\"\n}"]
D2 --> S2["Gunakan module:\nmodule \"pipeline\" {\n source = \"company/data/aws\"\n}"]
D3 --> S3["Gunakan module:\nmodule \"mobile\" {\n source = \"company/api/aws\"\n}"]
style Platform fill:#e3f2fd,stroke:#1565c0
style Dev fill:#e8f5e9,stroke:#2e7d32Terraform dalam Ekosistem DevOps #
Terraform bukan tool yang berdiri sendiri — ia adalah bagian dari ekosistem DevOps yang lebih besar. Memahami bagaimana Terraform berinteraksi dengan tool lain membantu kamu merancang workflow yang efisien.
Terraform + CI/CD #
# GitHub Actions: Terraform Plan di setiap PR
name: Terraform
on:
pull_request:
paths: ['terraform/**']
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- name: Terraform Init
run: terraform init
working-directory: terraform/
- name: Terraform Plan
run: terraform plan -out=tfplan
working-directory: terraform/
- name: Comment PR with Plan
uses: actions/github-script@v7
with:
script: |
const { execSync } = require('child_process');
const plan = execSync('terraform show -no-color tfplan', {
cwd: 'terraform/'
}).toString();
github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: '## Terraform Plan\n```\n' + plan + '\n```'
});
Terraform + Monitoring #
# Setelah Terraform membuat resource, otomatis tambahkan monitoring
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.medium"
tags = { Name = "web-server", Environment = "production" }
}
# CloudWatch alarm — bagian dari infrastruktur yang sama
resource "aws_cloudwatch_metric_alarm" "cpu_high" {
alarm_name = "web-cpu-high"
comparison_operator = "GreaterThanThreshold"
evaluation_periods = 2
metric_name = "CPUUtilization"
namespace = "AWS/EC2"
period = 300
statistic = "Average"
threshold = 80
alarm_description = "CPU utilization exceeds 80%"
dimensions = {
InstanceId = aws_instance.web.id
}
alarm_actions = [aws_sns_topic.alerts.arn]
}
Terraform + Kubernetes #
Terraform bisa membuat cluster Kubernetes (EKS, GKE, AKS), tapi untuk mengelola workload di dalam cluster, Helm atau Kustomize lebih tepat.
# Terraform: Buat EKS cluster
module "eks" {
source = "terraform-aws-modules/eks/aws"
version = "~> 19.0"
cluster_name = "my-cluster"
cluster_version = "1.28"
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnets
eks_managed_node_groups = {
general = {
desired_size = 3
min_size = 2
max_size = 5
instance_types = ["t3.large"]
}
}
}
# Helm: Deploy aplikasi ke cluster yang sudah dibuat Terraform
provider "helm" {
kubernetes {
host = module.eks.cluster_endpoint
cluster_ca_certificate = base64decode(module.eks.cluster_certificate_authority_data)
}
}
resource "helm_release" "nginx_ingress" {
name = "nginx-ingress"
repository = "https://kubernetes.github.io/ingress-nginx"
chart = "ingress-nginx"
namespace = "ingress-nginx"
create_namespace = true
set {
name = "controller.replicaCount"
value = "2"
}
}
flowchart TD
subgraph TerraformScope["Dikelola oleh Terraform"]
T1["VPC, Subnet, Security Groups"]
T2["EKS/GKE/AKS Cluster"]
T3["RDS, S3, ElastiCache"]
T4["IAM Roles & Policies"]
T5["DNS, CDN, Certificate"]
end
subgraph HelmScope["Dikelola oleh Helm/Kustomize"]
H1["Application Deployment"]
H2["Ingress Controller"]
H3["Monitoring Stack"]
H4["Service Mesh"]
end
subgraph CI_CDScope["Dikelola oleh CI/CD"]
C1["Build & Test"]
C2["Push Image"]
C3["Update Deployment"]
C4["Run Migrations"]
end
TerraformScope -->|"Cluster hidup"| HelmScope
HelmScope -->|"App deployed"| CI_CDScope
style TerraformScope fill:#e3f2fd,stroke:#1565c0
style HelmScope fill:#e8f5e9,stroke:#2e7d32
style CI_CDScope fill:#fff3e0,stroke:#e65100Anti-Pattern Penggunaan Terraform #
Berikut beberapa anti-pattern yang sering terjadi saat menggunakan Terraform:
Anti-Pattern 1: Menggunakan Terraform untuk Semua #
ANTI-PATTERN:
✗ Deploy aplikasi ke K8s dengan kubernetes_deployment resource
✗ Konfigurasi server dengan remote-exec provisioner
✗ Manage DNS record yang berubah setiap hari (rate limit API)
✗ Mengelola data seeding database
KENAPA BERBAHAYA:
✓ Terraform plan selalu menunjukkan perubahan
✓ Error handling sangat terbatas untuk operasi yang kompleks
✓ Mengabatkan batas tanggung jawab tool yang tepat
Anti-Pattern 2: Tidak Menggunakan Module #
ANTI-PATTERN:
✗ Copy-paste resource block untuk setiap environment
✗ Mengubah parameter secara manual antar environment
✗ Tidak ada standarisasi naming convention
KENAPA BERBAHAYA:
✓ Perubahan di satu environment lupa di-propagate ke yang lain
✓ Inconsistency antar environment
✓ Duplikasi kode yang sulit di-maintain
BENAR:
✓ Buat module untuk setiap komponen infrastruktur
✓ Parameterize dengan variable
✓ Share module melalui registry
Anti-Pattern 3: State di Local untuk Tim #
ANTI-PATTERN:
✗ State file di laptop masing-masing engineer
✗ Tidak ada state locking
✗ Push state file ke Git (berisi secret!)
BENAR:
✓ Remote state di S3/GCS/Azure Blob
✓ State locking dengan DynamoDB/consul
✓ State file TIDAK PERNAH masuk Git
Ringkasan #
- Gunakan Terraform untuk multi-cloud infrastructure, reproducible environments, tim yang butuh konsistensi, compliance requirement, dan disaster recovery.
- Jangan gunakan Terraform untuk konfigurasi server (gunakan Ansible/Chef/Puppet), deployment aplikasi (gunakan CI/CD), atau workload Kubernetes murni (gunakan Helm/Kustomize).
- Solo developer bisa mulai sederhana — satu direktori, state local, langsung apply. Tapi segera pindahkan ke remote state begitu ada tim.
- Tim kecil butuh remote state + Git workflow + PR review. Ini kombinasi minimum yang efektif.
- Tim besar perlu dedicated platform team, module registry, policy as code (OPA/Sentinel), dan self-service untuk developer.
- Terraform bukan tool yang berdiri sendiri — berintegrasi dengan CI/CD, monitoring, Kubernetes, dan tool DevOps lainnya untuk workflow yang lengkap.
- Hindari anti-pattern: jangan gunakan Terraform untuk semua, selalu gunakan module, dan simpan state di remote backend dengan locking.
← Sebelumnya: Alternatif Terraform Berikutnya: Paradigma Deklaratif →