Execution Plan #
Ketika kamu menjalankan terraform plan, Terraform tidak hanya membuat daftar perubahan secara acak. Di balik layar, ia membangun dependency graph yang menentukan urutan eksekusi yang tepat, resource mana yang bisa dijalankan paralel, dan resource mana yang harus menunggu yang lain selesai dulu. Memahami bagaimana execution plan dibangun membantumu menulis konfigurasi yang lebih efisien dan men-debug masalah yang tidak terlihat jelas dari permukaan.
Apa itu Dependency Graph #
Dependency graph adalah struktur data yang Terraform bangun dari konfigurasimu. Setiap resource adalah node dalam graph, dan setiap referensi antar resource adalah edge (arah dependency).
# Konfigurasi ini:
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id # ← edge: subnet → VPC
cidr_block = "10.0.1.0/24"
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id # ← edge: IGW → VPC
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id # ← edge: route table → VPC
}
resource "aws_instance" "web" {
subnet_id = aws_subnet.public.id # ← edge: instance → subnet
ami = var.ami_id
}
DEPENDENCY GRAPH yang dibangun Terraform:
aws_vpc.main
│
├──────────────────┬──────────────────┐
│ │ │
▼ ▼ ▼
aws_subnet.public aws_internet_gateway aws_route_table.public
│
▼
aws_instance.web
Urutan eksekusi:
1. aws_vpc.main (tidak ada dependency — dieksekusi pertama)
2. aws_subnet.public, aws_internet_gateway, aws_route_table.public
(ketiganya bergantung pada VPC, tapi tidak satu sama lain
→ dieksekusi PARALEL setelah VPC selesai)
3. aws_instance.web (bergantung pada subnet → tunggu subnet selesai)
Paralelisme dalam Execution Plan #
Terraform secara otomatis mengeksekusi resource secara paralel selama tidak ada dependency di antara mereka. Ini membuat Terraform jauh lebih efisien dari script sequential.
SEQUENTIAL (script bash):
VPC: ████ (2s)
Subnet: ░░░░████ (4s setelah VPC)
IGW: ░░░░░░░░████ (6s setelah subnet)
RT: ░░░░░░░░░░░░████ (8s setelah IGW)
Total: ~14 detik (semua sequential)
PARALEL (Terraform):
VPC: ████ (2s)
Subnet: ░░░░████ (mulai setelah VPC, selesai di t=6s)
IGW: ░░░░████ (mulai bersamaan dengan subnet)
RT: ░░░░████ (mulai bersamaan dengan subnet dan IGW)
Total: ~6 detik (VPC lalu paralel)
Default paralelisme adalah 10 — artinya hingga 10 resource bisa dieksekusi bersamaan. Ini bisa disesuaikan dengan -parallelism=N.
Membaca Execution Plan secara Detail #
Output terraform plan menampilkan urutan yang akan Terraform lakukan, tapi tidak secara eksplisit menunjukkan paralelisme. Kamu bisa melihat dependency graph secara visual.
# Generate dependency graph dalam format DOT (Graphviz)
terraform graph
# Output (potongan):
# digraph {
# compound = "true"
# newrank = "true"
# "aws_vpc.main" -> "aws_subnet.public"
# "aws_vpc.main" -> "aws_internet_gateway.main"
# "aws_subnet.public" -> "aws_instance.web"
# }
# Render ke gambar (butuh Graphviz terinstall)
terraform graph | dot -Tsvg > graph.svg
terraform graph | dot -Tpng > graph.png
# Untuk plan spesifik (bukan konfigurasi saat ini)
terraform graph -plan=tfplan
Explicit Dependency dengan depends_on #
Terraform menyimpulkan dependency dari referensi langsung (aws_vpc.main.id). Tapi ada kasus di mana dependency tidak terlihat dari referensi — misalnya ketergantungan pada side effect.
# KASUS: EKS Node Group butuh IAM policy sudah ter-attach ke role
# Dependency ini tidak bisa disimpulkan dari referensi resource saja
resource "aws_iam_role" "node" {
name = "eks-node-role"
# ...
}
resource "aws_iam_role_policy_attachment" "node_policy" {
role = aws_iam_role.node.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
}
resource "aws_eks_node_group" "workers" {
cluster_name = aws_eks_cluster.main.name
node_role_arn = aws_iam_role.node.arn
# Tanpa depends_on ini, node group mungkin dibuat sebelum
# policy selesai di-attach ke role
depends_on = [
aws_iam_role_policy_attachment.node_policy
]
}
# ANTI-PATTERN: Menggunakan depends_on berlebihan
resource "aws_subnet" "public" {
depends_on = [aws_vpc.main] # ✗ Tidak perlu — referensi vpc_id sudah cukup
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
}
# BENAR: Biarkan referensi menentukan dependency secara otomatis
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id # ✓ Dependency sudah tersirat dari sini
cidr_block = "10.0.1.0/24"
}
Execution Plan dalam Format JSON #
Untuk integrasi dengan tooling eksternal (CI/CD, policy checker, notifikasi), execution plan bisa diekspor dalam format JSON.
# Generate plan dan export ke JSON
terraform plan -out=tfplan
terraform show -json tfplan > plan.json
# Struktur JSON plan (potongan):
# {
# "format_version": "1.2",
# "resource_changes": [
# {
# "address": "aws_instance.web",
# "change": {
# "actions": ["create"],
# "before": null,
# "after": {
# "ami": "ami-0abcdef1234567890",
# "instance_type": "t3.micro"
# }
# }
# }
# ]
# }
# Contoh: Cek apakah ada resource yang akan di-destroy menggunakan jq
terraform show -json tfplan | \
jq '[.resource_changes[] | select(.change.actions[] == "delete")] | length'
# Output: 0 (tidak ada yang akan dihapus)
Ringkasan #
- Dependency graph dibangun otomatis dari referensi antar resource — kamu tidak perlu menentukan urutan eksekusi secara manual.
- Resource independen dieksekusi paralel — Terraform secara default menjalankan hingga 10 operasi bersamaan untuk efisiensi maksimal.
terraform graphmenghasilkan visualisasi dependency graph — berguna untuk memahami konfigurasi yang kompleks.depends_onuntuk side-effect dependency — gunakan hanya ketika dependency tidak bisa disimpulkan dari referensi langsung.- Jangan over-gunakan
depends_on— setiapdepends_oneksplisit mengurangi paralelisme dan bisa memperlambat apply.- Export plan ke JSON untuk integrasi dengan CI/CD — memungkinkan pemeriksaan programatik seperti “tidak ada resource yang di-destroy”.