ST
ShowTech VN
🏠 Trang Chủ
📖 Về ShowTech 📬 Liên Hệ

[Bài 02] Giải Mã Workflow Terraform: Cơ Chế Hoạt Động Ngầm Của Init, Plan, Apply & Đồ Thị DAG

[Bài 02] Giải Mã Workflow Terraform: Cơ Chế Hoạt Động Ngầm Của Init, Plan, Apply & Đồ Thị DAG

Hầu hết các kỹ sư khi bắt đầu với Terraform đều thuộc lòng bộ ba câu lệnh quen thuộc: terraform init, terraform planterraform apply. Tuy nhiên, khi vận hành hệ thống quy mô lớn với hàng trăm tài nguyên phân tán, việc hiểu rõ cơ chế ngầm (under-the-hood) của từng giai đoạn thực thi là yếu tố quyết định giúp bạn tối ưu hóa thời gian chạy pipeline từ 45 phút xuống dưới 3 phút và ngăn chặn thảm họa xóa nhầm tài nguyên cơ sở dữ liệu.

Trong bài viết này, chúng ta sẽ mổ xẻ chi tiết chu trình thực thi 2 pha (Two-Phase Execution), cấu trúc Đồ thị không tuần hoàn có hướng (Directed Acyclic Graph - DAG) và cách Terraform điều phối hàng chục luồng gọi Cloud API đồng thời.


1. Toàn Cảnh Chu Trình Vòng Đời Terraform Core Workflow

Khi bạn thực hiện các lệnh CLI, Terraform Core phối hợp chặt chẽ với các Provider Plugins độc lập qua giao thức gRPC nội bộ.


2. Giải Phẫu Chuyên Sâu Từng Giai Đoạn

2.1. terraform init — Quản Trị Dependency & Provider Plugins

init là bước chuẩn bị môi trường làm việc. Khi chạy lệnh này, Terraform thực hiện 3 nhiệm vụ quan trọng:
1. Provider Discovery & Locking: Đọc khối terraform.required_providers trong code, tải chính xác binary tương thích với OS/Architecture về thư mục .terraform/ và tạo/cập nhật tệp .terraform.lock.hcl chứa mã băm SHA-256 (Checksum).
2. Module Installation: Tải các child modules từ local, Git repo hoặc Terraform Registry về .terraform/modules/.
3. Backend Initialization: Kết nối tới Remote State (như AWS S3, GCS, Azure Blob, HCP Terraform) và cấu hình cơ chế khóa đồng thời (State Locking).

🚀 Mẹo Thực Chiến

Best Practice trong CI/CD: Luôn commit file .terraform.lock.hcl vào Git repository để đảm bảo 100% môi trường build (Local, Staging, Production) sử dụng chung một phiên bản Provider binary giống hệt nhau, loại bỏ hoàn toàn lỗi không tương thích.


2.2. terraform plan — Cơ Chế Two-Phase Execution & Xây Dựng DAG

Lệnh plan là trung tâm tính toán thông minh nhất của Terraform. Quá trình này diễn ra qua 2 pha liên tiếp:

Pha 1: Refresh State (Đối Soát Thực Tế)

Terraform đọc State file hiện tại, sau đó gửi yêu cầu tới các Provider plugin để gọi API lên Cloud (ví dụ: DescribeVpcs, DescribeSubnets) nhằm kiểm tra xem tài nguyên có bị thay đổi ngoài ý muốn (State Drift) bởi ai đó chỉnh tay trên Console hay không.

Pha 2: Diff Graph & Topological Sort

Terraform phân tích toàn bộ mã nguồn HCL, đối chiếu với Live State sau bước Refresh, và xây dựng một Đồ thị không tuần hoàn có hướng (Directed Acyclic Graph - DAG). Đồ thị này biểu diễn mối quan hệ phụ thuộc giữa các tài nguyên:

Dựa trên thuật toán sắp xếp Topo (Topological Sort), Terraform xác định chính xác:
- Tài nguyên nào phải tạo trước (ví dụ: VPC phải có trước Subnet).
- Tài nguyên nào độc lập có thể tạo song song (ví dụ: Subnet A và Subnet B).
- Tài nguyên nào bị sửa đổi tại chỗ (in-place update ~) hoặc bắt buộc phải hủy tạo lại (destroy and re-create -/+).


2.3. terraform apply — Thực Thi Kế Hoạch & Đồng Bộ State

Khi nhận được sự xác nhận (yes hoặc thông qua plan file đã lưu), Terraform kích hoạt worker pool (mặc định -parallelism=10 luồng song song) để gửi các lệnh thay đổi lên Cloud API.


3. Kiến Trúc Mẫu Triển Khai VPC High Availability Chuẩn HCL 1.7+

Dưới đây là cấu hình mạng đa vùng sẵn sàng cao (Multi-AZ VPC) thể hiện rõ cấu trúc phụ thuộc phân tầng trong DAG:

HCL
# network-core.tf - Kiến trúc VPC phân lớp chuẩn Enterprise
variable "aws_region" {
  type        = string
  default     = "ap-southeast-1"
  description = "Region triển khai hạ tầng chính"
}

variable "vpc_cidr" {
  type        = string
  default     = "10.100.0.0/16"
  description = "CIDR block cho VPC Production"
}

variable "availability_zones" {
  type        = list(string)
  default     = ["ap-southeast-1a", "ap-southeast-1b"]
  description = "Danh sách Availability Zones phân bổ"
}

# 1. Khởi tạo VPC gốc
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name        = "showtech-prod-vpc"
    Environment = "production"
    Tier        = "network"
  }
}

# 2. Tạo Public Subnets đa vùng
resource "aws_subnet" "public" {
  count                   = length(var.availability_zones)
  vpc_id                  = aws_vpc.main.id
  cidr_block              = cidrsubnet(var.vpc_cidr, 8, count.index + 1)
  availability_zone       = var.availability_zones[count.index]
  map_public_ip_on_launch = true

  tags = {
    Name = "showtech-public-subnet-${var.availability_zones[count.index]}"
    Type = "Public"
  }
}

# 3. Internet Gateway kết nối ra bên ngoài
resource "aws_internet_gateway" "igw" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name = "showtech-prod-igw"
  }
}

# 4. Route Table cho Public Subnets
resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.igw.id
  }

  tags = {
    Name = "showtech-public-rt"
  }
}

resource "aws_route_table_association" "public" {
  count          = length(aws_subnet.public)
  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}

4. Production War Story: Tối Ưu Hóa Tốc Độ Thực Thi Lớn

ℹ️ Lưu Ý / Tình Huống

Bài toán thực tế: Một hệ thống hạ tầng gồm 850 tài nguyên AWS (EKS, RDS, VPC Peering, CloudFront, Route53) mất hơn 38 phút cho mỗi lần chạy terraform plan. Khiến quy trình deploy hotfix bị đình trệ.

Nguyên Nhân Gốc Rễ:

  1. Mỗi lần plan, Terraform thực hiện 850 cuộc gọi API tuần tự/song song giới hạn lên AWS để kiểm tra Refresh. AWS API bắt đầu kích hoạt cơ chế Throttling (Rate Limiting HTTP 429).
  2. Codebase được đặt chung trong một thư mục duy nhất (Monolithic State), làm phình to kích thước file state lên hơn 45MB.

Giải Pháp Đã Áp Dụng:

  1. Phân rã State theo tầng (Layering Architecture): Tách hạ tầng tĩnh (Network/VPC - ít thay đổi) khỏi hạ tầng động (EKS/App Instances).
  2. Khai thác -refresh=false hoặc -target có chọn lọc: Khi chỉ cần deploy cấu hình ứng dụng trong pipeline CI, bỏ qua bước refresh toàn bộ VPC.
  3. Điều chỉnh tham số Parallelism: Tăng -parallelism=30 đối với các tài nguyên độc lập như IAM Roles hoặc Security Group Rules.

Kết quả: Thời gian chạy planapply giảm từ 38 phút xuống còn 2 phút 15 giây (giảm 94%).


5. Câu Hỏi Phỏng Vấn Kỹ Sư Cao Cấp (Senior Terraform Q&A)

Q1: Sự khác biệt giữa terraform plan -out=tfplan và việc chạy terraform apply trực tiếp không kèm plan file là gì? Tại sao các hệ thống tài chính bắt buộc dùng -out?

Trả lời:
Khi chạy terraform plan -out=tfplan, Terraform đóng gói toàn bộ đồ thị DAG, diff tính toán, và mã checksum của State tại thời điểm đó vào một file nhị phân tĩnh. Khi chạy terraform apply tfplan, Terraform cam kết chỉ thực thi chính xác những gì đã được ghi trong plan file, tuyệt đối không tính toán lại hay refresh lại. Điều này ngăn ngừa triệt để lỗi Race Condition (nếu có ai đó sửa đổi hạ tầng trong khoảng thời gian giữa lúc plan và apply).

Q2: Điều gì sẽ xảy ra nếu trong mã nguồn HCL xuất hiện một vòng lặp phụ thuộc (Cyclic Dependency), ví dụ: Resource A phụ thuộc B, và B lại tham chiếu ngược lại A?

Trả lời:
Terraform sẽ dừng ngay ở bước plan và ném ra lỗi Error: Cycle in resource graph. Thuật toán DAG không cho phép tồn tại chu trình khép kín. Để giải quyết, kỹ sư phải tách điểm phụ thuộc trung gian bằng cách sử dụng tài nguyên liên kết riêng biệt (ví dụ: tách aws_security_group_rule ra khỏi aws_security_group).


6. Tổng Kết

Nắm vững chu trình Two-Phase Execution và Đồ thị DAG giúp bạn làm chủ hoàn toàn quá trình điều phối hạ tầng, tự tin gỡ lỗi các bài toán phụ thuộc phức tạp và tối ưu hiệu năng vận hành ở quy mô lớn.

Trong bài viết tiếp theo (Bài 03), chúng ta sẽ đi sâu vào Tối ưu hóa Cú pháp HCL: Làm chủ Dynamic Type, Heredoc, Built-in Functions và Conditional Expressions.


Bài viết thuộc Series đào tạo Terraform Thực Chiến độc quyền trên ShowTech.vn.

ShowTech Author

ShowTech Admin (ShowTech Team)

Cloud Architect & Senior DevOps Engineer

Đam mê xây dựng hệ thống phần mềm hiệu năng cao, phân tán quy mô lớn và chia sẻ tri thức công nghệ thực chiến chuẩn quốc tế cho cộng đồng kỹ sư Việt Nam.

Tìm kiếm Blog này

Bài đăng phổ biến từ blog này

Tối Ưu PostgreSQL Chịu Tải Hàng Triệu Queries: Indexing, Connection Pooling & Partitioning

Kiến Trúc Microservices Chịu Tải 1 Triệu CCU Thực Chiến

Tối Ưu Memory Footprint & Goroutine Pooling Trong High-Throughput Go Services

Đã sao chép liên kết vào clipboard!