Khi nào Terraform không còn đủ? Giới thiệu Terragrunt
Terraform rất mạnh, nhưng khi số lượng môi trường và module tăng lên, việc quản lý dần trở nên khó khăn. Trong bài viết này, chúng ta sẽ tìm hiểu những giới hạn của Terraform và lý do Terragrunt ra đời.

Khi nào Terraform không còn đủ? Giới thiệu Terragrunt
Suốt series này, chúng ta đã tìm hiểu khá nhiều về Terraform.
Từ những khái niệm cơ bản như Infrastructure as Code, cách Terraform hoạt động, Terraform State, Plan & Apply cho đến Variables, Data Sources, Remote State và cách tổ chức repository production.
Nếu chỉ nhìn vào những gì Terraform cung cấp, có thể bạn sẽ nghĩ:
"Terraform đã đủ để xây dựng mọi hệ thống."
Thực tế...
Đúng nhưng chưa đủ.
Terraform là một công cụ cực kỳ mạnh để quản lý infrastructure.
Nhưng Terraform không được thiết kế để giải quyết tất cả các bài toán liên quan đến việc quản lý nhiều môi trường, nhiều account và hàng trăm module khác nhau.
Đó cũng là lý do gần như mọi công ty sử dụng Terraform ở quy mô lớn đều bổ sung thêm một lớp quản lý phía trên.
Một trong những công cụ phổ biến nhất chính là Terragrunt.
Terraform rất giỏi ở việc Provision Infrastructure
Terraform làm rất tốt nhiệm vụ của mình:
- Quản lý Resource
- Theo dõi State
- Tính toán Dependency
- Tạo Execution Plan
- Apply thay đổi an toàn
Ví dụ:
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
}Terraform hiểu rằng:
VPC
↓
Subnet
Terraform sẽ tự tạo đúng thứ tự.
Nếu thay đổi Subnet:
Plan
↓
Update Subnet
VPC giữ nguyên
Nếu Resource phụ thuộc lẫn nhau:
IAM Role
↓
EC2
↓
Load Balancer
Terraform cũng tự xây dựng Dependency Graph.
Đây là điểm mạnh nhất của Terraform.
Nhưng Production không chỉ có một môi trường
Khi mới bắt đầu học Terraform, hầu hết ví dụ đều giống như thế này:
terraform-project
main.tf
variables.tf
outputs.tf
Chỉ có một thư mục.
Một môi trường.
Một State.
Điều này hoàn toàn ổn để học.
Nhưng khi triển khai thực tế, mọi chuyện nhanh chóng thay đổi.
Ví dụ:
Production
AWS Account A
├── VPC
├── Network
├── EKS
├── RDS
└── Monitoring
Staging
AWS Account B
├── VPC
├── Network
├── EKS
├── RDS
└── Monitoring
Development
AWS Account C
├── VPC
├── Network
├── EKS
├── RDS
└── Monitoring
Đột nhiên chúng ta không còn quản lý:
- 1 môi trường
mà là:
- 3 môi trường
- nhiều AWS Account
- nhiều Region
- hàng chục Terraform Module
Sự lặp lại bắt đầu xuất hiện
Giả sử bạn đã viết xong một module VPC.
modules/
vpc/
Bây giờ bạn cần dùng module này cho ba môi trường.
dev
staging
production
Thông thường bạn sẽ có:
live/
dev/
vpc/
staging/
vpc/
production/
vpc/
Trong mỗi thư mục lại có một file gần giống nhau.
Ví dụ:
module "vpc" {
source = "../../modules/vpc"
cidr = "10.0.0.0/16"
environment = "dev"
}Staging:
module "vpc" {
source = "../../modules/vpc"
cidr = "10.1.0.0/16"
environment = "staging"
}Production:
module "vpc" {
source = "../../modules/vpc"
cidr = "10.2.0.0/16"
environment = "production"
}Thoạt nhìn thì không có vấn đề gì.
Nhưng khi số module tăng lên:
- VPC
- IAM
- EKS
- RDS
- Redis
- S3
- CloudFront
- Route53
- Monitoring
- Logging
- WAF
- Secrets
...
Mỗi môi trường đều phải lặp lại gần như toàn bộ cấu hình.
Không chỉ lặp code
Điều khó chịu hơn là những thông tin dùng chung.
Ví dụ:
Backend:
terraform {
backend "s3" {
bucket = "company-tfstate"
}
}Provider:
provider "aws" {
region = "ap-southeast-1"
}Common Tags:
tags = {
Team = "Platform"
Owner = "Infrastructure"
}Remote State:
data "terraform_remote_state" ...Provider Version:
terraform {
required_providers {
aws = {
version = "~> 6.0"
}
}
}Những đoạn cấu hình này gần như xuất hiện ở mọi module.
Nếu có 50 module và 4 môi trường, bạn có thể đang duy trì hàng trăm file Terraform gần giống nhau.
Đó là lúc việc bảo trì bắt đầu trở nên tốn kém.
Terraform không biết "Environment"
Một điều khá thú vị là Terraform không hề có khái niệm:
- Development
- Staging
- Production
Terraform chỉ biết:
Working Directory
Ví dụ:
live/
dev/
app/
staging/
app/
production/
app/
Đối với Terraform, ba thư mục trên hoàn toàn độc lập.
Terraform không hiểu rằng:
dev
↓
staging
↓
production
là ba phiên bản của cùng một hệ thống.
Terraform cũng không biết:
- Environment nào thuộc cùng một project
- Account nào thuộc Production
- Region nào đang được sử dụng
- Module nào nên dùng chung cấu hình
Mọi thứ đều do người dùng tự tổ chức.
Điều này mang lại sự linh hoạt rất lớn, nhưng cũng khiến việc quản lý trở nên khó khăn khi hệ thống ngày càng mở rộng.
Terraform cũng không quản lý Repository
Terraform chỉ đọc thư mục hiện tại.
Ví dụ:
terraform apply
Terraform sẽ đọc:
.
├── main.tf
├── variables.tf
└── outputs.tf
Nó không quan tâm:
company-iac/
projects/
platform/
network/
production/
hay
live/
modules/
shared/
được tổ chức như thế nào.
Terraform cũng không áp đặt:
- cách đặt tên thư mục
- cách chia module
- cách quản lý environment
- cách quản lý account
- cách quản lý backend
- cách chia repository
Điều đó có nghĩa là hai công ty đều dùng Terraform nhưng repository có thể hoàn toàn khác nhau.
Ví dụ:
Company A
production/
staging/
development/
Company B
aws/
azure/
gcp/
Company C
platform/
application/
security/
network/
Tất cả đều hợp lệ.
Terraform không hề kiểm tra điều này.
Khi hệ thống lớn dần
Hãy tưởng tượng một công ty có:
- 4 AWS Account
- 3 Region
- 6 Environment
- 80 Terraform Module
Nếu mỗi module đều có:
main.tf
providers.tf
backend.tf
versions.tf
variables.tf
thì tổng số file sẽ lên tới hàng trăm.
Điều đáng nói là phần lớn nội dung của chúng lại giống nhau.
Ví dụ:
Backend giống nhau.
terraform {
backend "s3" {
bucket = "company-state"
}
}Provider giống nhau.
provider "aws" {
region = "ap-southeast-1"
}Version giống nhau.
terraform {
required_version = ">= 1.8"
}Tags giống nhau.
tags = {
ManagedBy = "Terraform"
}Chỉ cần thay đổi một quy định nhỏ, chẳng hạn:
- đổi bucket chứa State
- nâng phiên bản Provider
- thêm một Tag bắt buộc
- thay đổi cấu hình Assume Role
bạn có thể phải cập nhật hàng chục hoặc hàng trăm thư mục.
Đây không phải là vấn đề của Terraform.
Đơn giản là Terraform chưa bao giờ được thiết kế để quản lý những quy ước ở cấp độ repository.
Những cách mọi người từng cố gắng giải quyết
Trước khi Terragrunt trở nên phổ biến, rất nhiều team đã tự xây dựng cách tổ chức riêng.
Ví dụ:
Dùng Symbolic Link.
backend.tf
↓
ln -s
Hoặc tạo script để copy file.
copy backend.tf
↓
100 folders
Một số team dùng Bash.
for dir in */ ; do
cp backend.tf "$dir"
doneMột số khác dùng Makefile.
apply-all:Hoặc tự viết wrapper bằng Python.
python deploy.py
Thậm chí có team xây dựng hẳn một công cụ nội bộ để quản lý Terraform.
Tất cả những cách làm này đều hướng tới cùng một mục tiêu:
Giảm việc lặp cấu hình và giúp repository dễ quản lý hơn.
Điều đó cho thấy nhu cầu này là có thật.
Và cũng chính từ những bài toán đó, Terragrunt được tạo ra.
Terragrunt không thay thế Terraform
Đây là điều rất nhiều người mới học thường hiểu nhầm.
Terragrunt không phải là phiên bản mới của Terraform.
Terragrunt cũng không tạo Resource.
Nó không gọi API của AWS.
Không quản lý State.
Không tính Dependency Graph.
Không thực hiện Provision Infrastructure.
Thực tế, quy trình vẫn là:
Terragrunt
↓
Terraform
↓
Cloud Provider
Hay nói cách khác:
Terragrunt chỉ đứng phía trước Terraform.
Nó giúp:
- chuẩn bị cấu hình
- tổ chức repository
- giảm lặp code
- truyền biến
- quản lý nhiều module
- quản lý nhiều environment
Cuối cùng, chính Terraform mới là công cụ thực hiện plan và apply.
Vì vậy, nếu chưa hiểu Terraform thì cũng sẽ rất khó sử dụng Terragrunt hiệu quả.
Terragrunt được sinh ra để bổ sung cho Terraform, chứ không phải để thay thế Terraform.
Terragrunt giải quyết điều gì?
Nếu phải mô tả Terragrunt bằng một câu ngắn gọn, mình sẽ nói:
Terragrunt là một lớp quản lý (wrapper) giúp Terraform dễ sử dụng hơn trong các dự án thực tế.
Nó không thay đổi cách Terraform hoạt động.
Nó chỉ giúp chúng ta giảm những công việc lặp đi lặp lại mà Terraform không xử lý.
Ví dụ:
Thay vì mỗi module đều phải khai báo Backend:
terraform {
backend "s3" {
bucket = "company-state"
key = "..."
region = "ap-southeast-1"
}
}Terragrunt cho phép định nghĩa một lần và tái sử dụng ở nhiều nơi.
Tương tự với:
- Provider
- Common Variables
- Common Tags
- Remote State
- Provider Version
- Naming Convention
Điều này giúp repository gọn gàng hơn rất nhiều.
Những khả năng nổi bật của Terragrunt
Trong những bài tiếp theo của series, chúng ta sẽ đi sâu vào từng tính năng.
Ở thời điểm này, chỉ cần hình dung Terragrunt có thể hỗ trợ:
Giảm lặp cấu hình
Một cấu hình dùng chung có thể được chia sẻ cho toàn bộ repository.
Root Configuration
│
├── Dev
├── Staging
└── Production
Thay vì copy cùng một đoạn HCL vào hàng chục thư mục.
Quản lý nhiều Environment
Một repository có thể chứa:
live/
dev/
staging/
production/
Terragrunt giúp các môi trường này kế thừa cùng một cấu hình gốc nhưng vẫn dễ dàng ghi đè những giá trị cần thiết.
Quản lý nhiều Account và Region
Ví dụ:
AWS
Production
ap-southeast-1
us-east-1
Development
ap-southeast-1
Terragrunt giúp việc tổ chức những cấu trúc như vậy trở nên rõ ràng hơn.
Chạy nhiều Module theo đúng thứ tự
Ví dụ:
Network
↓
Database
↓
EKS
↓
Applications
Terragrunt có thể hỗ trợ chạy các module theo đúng thứ tự phụ thuộc mà không cần bạn thực hiện thủ công từng thư mục.
Chuẩn hóa Repository
Một trong những lợi ích lớn nhất của Terragrunt là giúp toàn bộ team cùng làm việc theo một cấu trúc thống nhất.
Thay vì mỗi người tự nghĩ ra cách tổ chức repository riêng, cả team có thể sử dụng cùng một convention, giúp việc bảo trì và mở rộng về sau dễ dàng hơn.
Có phải dự án nào cũng cần Terragrunt?
Câu trả lời là:
Không.
Nếu dự án của bạn chỉ có:
- một môi trường
- vài resource
- một hoặc hai module
thì Terraform thuần thường đã là lựa chọn đơn giản và hiệu quả.
Việc bổ sung thêm Terragrunt trong trường hợp này có thể khiến dự án phức tạp hơn mức cần thiết.
Ngược lại, khi hệ thống bắt đầu có:
- nhiều environment
- nhiều cloud account
- nhiều region
- nhiều team cùng phát triển
- hàng chục hoặc hàng trăm module
thì việc quản lý chỉ bằng Terraform sẽ dần trở nên khó khăn.
Đó là lúc Terragrunt phát huy giá trị.
Điều quan trọng cần nhớ là:
Đừng sử dụng Terragrunt chỉ vì "mọi người đều dùng".
Hãy sử dụng nó khi những bài toán mà Terragrunt giải quyết thực sự xuất hiện trong dự án của bạn.
Tổng kết
Terraform là một công cụ tuyệt vời để quản lý hạ tầng.
Nhưng Terraform tập trung vào việc provision infrastructure, chứ không nhằm mục tiêu quản lý toàn bộ cấu trúc của một repository lớn.
Khi số lượng module, environment và cloud account tăng lên, việc lặp cấu hình và tổ chức repository sẽ trở thành một thách thức.
Terragrunt ra đời để giải quyết chính những bài toán đó bằng cách bổ sung một lớp quản lý phía trên Terraform, giúp giảm lặp, chuẩn hóa cấu trúc và đơn giản hóa việc vận hành các hệ thống Infrastructure as Code ở quy mô lớn.
Bài tiếp theo
Ở bài tiếp theo, chúng ta sẽ bắt đầu đi sâu vào Terragrunt với câu hỏi đầu tiên:
Terragrunt là gì và nó hoạt động như thế nào?
Chúng ta sẽ tìm hiểu kiến trúc của Terragrunt, cách nó hoạt động cùng Terraform, đồng thời xây dựng project Terragrunt đầu tiên để hiểu rõ vai trò của công cụ này trong một hệ thống Infrastructure as Code hiện đại.
Bình luận
Đang tải bình luận…