Dependency #
Infrastruktur cloud jarang berdiri sendiri. Sebuah EC2 instance butuh subnet, subnet butuh VPC, VPC butuh internet gateway untuk akses publik. Terraform perlu tahu urutan yang benar untuk membuat dan menghapus semua resource ini. Cara Terraform mengelola dependency — secara otomatis maupun eksplisit — adalah salah satu fitur yang paling membedakannya dari pendekatan scripting tradisional.
Implicit Dependency #
Implicit dependency adalah dependency yang Terraform simpulkan secara otomatis dari referensi antar resource. Ini adalah cara yang paling umum dan paling direkomendasikan untuk mendefinisikan dependency.
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
# Referensi ke aws_vpc.main.id secara otomatis membuat
# Terraform tahu bahwa subnet ini bergantung pada VPC
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
}
resource "aws_internet_gateway" "main" {
# IGW juga bergantung pada VPC
vpc_id = aws_vpc.main.id
}
resource "aws_instance" "web" {
ami = var.ami_id
# Instance bergantung pada subnet
subnet_id = aws_subnet.public.id
}
# Dependency graph yang terbentuk:
#
# aws_vpc.main
# │
# ┌────┴────┐
# │ │
# ▼ ▼
# subnet igw
# │
# ▼
# instance
Terraform menghitung graph ini secara otomatis. Kamu tidak perlu menulis satu baris pun kode tambahan untuk mendefinisikan urutan.
Explicit Dependency dengan depends_on #
Ada kasus di mana dependency tidak bisa disimpulkan dari referensi langsung. Ini terjadi ketika resource bergantung pada efek samping dari resource lain, bukan pada atributnya.
# KASUS NYATA: EKS Node Group bergantung pada IAM policy yang sudah ter-attach
resource "aws_iam_role" "node" {
name = "eks-node-role"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = { Service = "ec2.amazonaws.com" }
}]
})
}
resource "aws_iam_role_policy_attachment" "eks_worker_node" {
role = aws_iam_role.node.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
}
resource "aws_iam_role_policy_attachment" "eks_cni" {
role = aws_iam_role.node.name
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
}
resource "aws_eks_node_group" "workers" {
cluster_name = aws_eks_cluster.main.name
node_role_arn = aws_iam_role.node.arn # Referensi ke role ada
subnet_ids = aws_subnet.private[*].id
scaling_config {
desired_size = 2
max_size = 5
min_size = 1
}
# Tanpa depends_on ini, node group mungkin mulai dibuat sebelum
# semua policy selesai di-attach ke role.
# aws_iam_role.node.arn tidak menjamin policy sudah ter-attach.
depends_on = [
aws_iam_role_policy_attachment.eks_worker_node,
aws_iam_role_policy_attachment.eks_cni,
]
}
Kapan Menggunakan depends_on #
GUNAKAN depends_on JIKA:
✓ Resource bergantung pada efek samping resource lain
(bukan pada nilai atributnya)
✓ Urutan yang benar tidak bisa disimpulkan dari referensi
✓ Provider documentation eksplisit menyebutkan dependency tertentu
✓ Ada race condition yang tercatat karena timing IAM propagation
JANGAN GUNAKAN depends_on JIKA:
✗ Dependency sudah tersirat dari referensi langsung
(tambahan depends_on hanya menambah noise)
✗ Mencoba "memperlambat" eksekusi — ini bukan cara yang tepat
✗ Tidak yakin mengapa dibutuhkan — cari root cause yang sebenarnya
Anti-Pattern: Over-Using depends_on #
# ANTI-PATTERN: depends_on yang tidak perlu
resource "aws_subnet" "public" {
# Referensi vpc_id sudah membuat dependency implisit
# depends_on di bawah ini redundan dan hanya menambah kebingungan
depends_on = [aws_vpc.main] # ✗ Tidak perlu
vpc_id = aws_vpc.main.id # ✓ Dependency sudah ada di sini
cidr_block = "10.0.1.0/24"
}
# ANTI-PATTERN: depends_on ke seluruh module tanpa alasan spesifik
module "database" {
source = "./modules/database"
depends_on = [module.networking] # ✗ Terlalu broad
# Dependency yang terlalu luas mencegah paralelisme yang seharusnya bisa terjadi
# Sebutkan resource spesifik jika memang perlu
}
Dependency Antar Module #
Ketika menggunakan modul, dependency bisa melintasi batas modul.
module "vpc" {
source = "./modules/vpc"
cidr = "10.0.0.0/16"
}
module "eks" {
source = "./modules/eks"
# Referensi ke output module vpc — implicit dependency
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.private_subnet_ids
# EKS module akan dibuat setelah VPC module selesai
}
module "rds" {
source = "./modules/rds"
# RDS juga bergantung pada VPC — tapi independen dari EKS
# Terraform akan membuat RDS dan EKS secara PARALEL
# setelah VPC selesai
vpc_id = module.vpc.vpc_id
subnet_ids = module.vpc.database_subnet_ids
}
Melihat Dependency Graph #
# Generate dan visualisasikan dependency graph
terraform graph | dot -Tsvg > dependency-graph.svg
# Filter hanya resource tertentu (butuh grep/awk)
terraform graph | grep -A2 "aws_instance"
# Graph untuk plan yang sudah disimpan
terraform graph -plan=tfplan
Ringkasan #
- Implicit dependency adalah default — selalu prioritaskan referensi langsung untuk mendefinisikan dependency, bukan
depends_on.depends_onuntuk side-effect dependency — ketika resource bergantung pada efek samping (seperti IAM policy attachment) bukan pada nilai atribut.- Jangan over-use
depends_on— setiapdepends_onyang tidak perlu mengurangi paralelisme dan memperlambat apply.- Dependency melintasi module terbentuk dari referensi ke output module — mekanismenya sama dengan dependency antar resource biasa.
- Resource independen dieksekusi paralel — Terraform memaksimalkan efisiensi dengan menjalankan operasi yang tidak saling bergantung secara bersamaan.
terraform graphuntuk visualisasi — gunakan saat konfigurasi kompleks dan kamu perlu memahami urutan eksekusi yang sebenarnya.