Khi tạo hạ tầng, nhiều resource phụ thuộc vào nhau. Ví dụ EC2 instance cần security group, security group cần VPC. Terraform cần biết thứ tự tạo các resource này. Bài này mình giải thích hai cách Terraform xử lý điều đó.
1. Vấn đề: Tại sao cần quan tâm đến thứ tự?
Hình dung bạn đang xây nhà. Bạn không thể lắp cửa trước khi có tường. Hạ tầng AWS cũng vậy:
- Không thể gắn security group vào EC2 nếu security group chưa tồn tại
- Không thể tạo subnet nếu VPC chưa có
- Không thể deploy app nếu database chưa sẵn sàng
Terraform giải quyết điều này bằng dependency graph – một sơ đồ thể hiện resource nào phải tạo trước resource nào. Có hai cách để Terraform xây dựng graph này.
2. Implicit Dependencies – Terraform tự suy ra
Đây là cách phổ biến và được khuyến khích dùng hơn.
Khi bạn tham chiếu trực tiếp từ resource này sang resource khác, Terraform tự hiểu là resource được tham chiếu phải tạo trước.
resource "aws_security_group" "example" {
name = "example-sg"
description = "Example security group"
vpc_id = var.vpc_id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"
security_groups = [
aws_security_group.example.name # ← tham chiếu trực tiếp
]
tags = {
Name = "example-instance"
}
}
Dòng aws_security_group.example.name là điểm mấu chốt. Terraform đọc dòng này và hiểu:
aws_instance.example cần giá trị từ aws_security_group.example
→ aws_security_group.example phải tồn tại trước
→ tạo security group trước, rồi mới tạo EC2
Bạn không cần viết thêm gì cả. Terraform tự xây dependency graph từ các tham chiếu trong config.
Minh hoạ dependency graph
var.vpc_id
│
▼
aws_security_group.example
│
│ (aws_security_group.example.name)
▼
aws_instance.example
Terraform nhìn vào graph này và biết thứ tự thực thi: VPC variable → security group → EC2 instance.
2. Explicit Dependencies – Khai báo tường minh bằng depends_on
Đôi khi dependency không thể hiện qua tham chiếu trực tiếp trong config. Terraform không có cách nào tự suy ra, nên bạn phải khai báo thủ công bằng depends_on.
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"
depends_on = [
aws_security_group.example # ← khai báo tường minh
]
tags = {
Name = "example-instance"
}
}
depends_on nhận một list các resource. Terraform đọc và hiểu: “Trước khi tạo aws_instance này, hãy đảm bảo tất cả resource trong depends_on đã được tạo xong.”
Khi nào cần dùng depends_on?
Trường hợp hay gặp nhất là khi dependency tồn tại ngoài Terraform config – ví dụ một script chạy bên ngoài, hoặc một service phụ thuộc vào IAM policy được attach vào role, không phải vào resource trực tiếp:
resource "aws_iam_role_policy_attachment" "example" {
role = aws_iam_role.example.name
policy_arn = aws_iam_policy.example.arn
}
resource "aws_instance" "example" {
ami = "ami-12345678"
instance_type = "t2.micro"
# EC2 cần role đã có policy attach rồi mới start
# nhưng trong config không có tham chiếu trực tiếp nào
depends_on = [
aws_iam_role_policy_attachment.example
]
}
Ở đây aws_instance không tham chiếu trực tiếp đến aws_iam_role_policy_attachment, nhưng thực tế EC2 cần role đó đã có đủ permission trước khi khởi động. Terraform không thể tự suy ra điều này → phải dùng depends_on.
3. So sánh hai loại
| Implicit | Explicit (depends_on) |
|
|---|---|---|
| Cách khai báo | Tham chiếu trực tiếp (resource_type.name.attribute) |
Dùng keyword depends_on |
| Terraform tự phát hiện? | Có | Không, phải khai báo tay |
| Config gọn không? | Gọn hơn | Dài hơn một chút |
| Nên dùng khi | Dependency thể hiện qua giá trị của resource | Dependency không có tham chiếu trực tiếp trong config |
4. Nguyên tắc chung
Ưu tiên implicit dependency. Nếu bạn đang tham chiếu giá trị của resource A để dùng trong resource B, Terraform đã tự hiểu thứ tự rồi, không cần thêm depends_on nữa.
Chỉ dùng depends_on khi bạn chắc chắn có dependency thực sự nhưng config không thể hiện điều đó qua tham chiếu. Dùng depends_on thừa không gây lỗi, nhưng làm config khó đọc và đôi khi khiến Terraform chờ lâu hơn cần thiết.