IaCInfrastructure as Codeterraformterraform repository

Thiết kế Terraform Repository cho Production

Hướng dẫn cách tổ chức Terraform repository theo chuẩn production để dễ mở rộng, dễ review và quản lý nhiều môi trường như dev, staging và production.

22 thg 7, 20265 min readCập nhật 22 thg 7, 2026
Thiết kế Terraform Repository cho Production

Thiết kế Terraform Repository cho Production

Ở các bài trước, chúng ta đã tìm hiểu:

  • Terraform hoạt động như thế nào
  • Terraform State
  • Terraform Modules
  • Provider
  • Data Sources
  • Những tính năng Terraform sử dụng hằng ngày

Đến đây, chúng ta đã có đủ kiến thức để viết Terraform.

Nhưng khi bắt đầu áp dụng vào production, sẽ xuất hiện một vấn đề khác.

Không còn là viết được Terraform nữa.

Mà là...

Làm thế nào để hàng chục, hàng trăm file Terraform vẫn dễ quản lý sau nhiều năm?

Đây là lúc cách tổ chức repository trở nên quan trọng hơn cả syntax.


Dự án nhỏ thì cấu trúc nào cũng được

Rất nhiều tutorial bắt đầu với cấu trúc như sau:

terraform/

main.tf
variables.tf
outputs.tf
provider.tf
versions.tf

Hoặc:

terraform/

network.tf
compute.tf
database.tf
iam.tf

Đối với demo thì hoàn toàn ổn.

Nhưng production thì khác.

Sau vài tháng sẽ có thêm:

  • VPC
  • IAM
  • ECS
  • RDS
  • S3
  • CloudFront
  • Route53
  • Lambda
  • EventBridge
  • Monitoring
  • Secrets
  • ...

Một thư mục có hàng chục file .tf.

Lúc này việc tìm một resource cũng trở nên khó khăn.


Sai lầm phổ biến

Rất nhiều team tổ chức repository theo service.

Ví dụ:

terraform/

ec2/
rds/
s3/
iam/
route53/

Thoạt nhìn có vẻ hợp lý.

Nhưng thực tế Terraform không hoạt động theo thư mục.

Terraform hoạt động theo state.

Nếu tất cả đều nằm trong cùng một state thì việc chia thư mục gần như chỉ mang tính hình thức.

Ngược lại, nếu mỗi thư mục là một state riêng thì dependency giữa chúng sẽ nhanh chóng trở nên phức tạp.


Hãy nghĩ theo Environment trước

Production thường có nhiều môi trường:

Development

Staging

Production

Mỗi môi trường sẽ có:

  • tài nguyên riêng
  • state riêng
  • pipeline riêng
  • quyền truy cập riêng

Do đó điều đầu tiên nên tách là:

live/

dev/

staging/

production/

Đây cũng là cách nhiều tổ chức lớn quản lý Infrastructure.


Tiếp theo là chia theo Infrastructure

Ví dụ:

live/

production/

network/

compute/

database/

monitoring/

Mỗi thư mục đại diện cho một stack.

Ví dụ:

network

sẽ quản lý

  • VPC
  • Subnets
  • NAT Gateway
  • Internet Gateway

Trong khi

database

chỉ quản lý

  • RDS
  • Parameter Groups
  • Subnet Groups

Như vậy mỗi stack sẽ có state riêng.


Modules không nên nằm trong live

Một sai lầm phổ biến khác.

live/

production/

modules/

vpc/

ecs/

Thực tế:

Modules là code có thể tái sử dụng.

Environment chỉ là nơi sử dụng module.

Do đó nên tách riêng.

repository/

modules/

vpc/

ecs/

rds/

live/

dev/

production/

Khi đó:

live

chỉ chứa configuration.

Còn

modules

chứa implementation.


Repository chuẩn thường trông như thế nào?

terraform/

modules/

vpc/

ecs/

rds/

iam/

s3/

live/

dev/

network/

compute/

database/

production/

network/

compute/

database/

Đây là layout phổ biến của rất nhiều repository Terraform production.

Bạn sẽ thấy cấu trúc này xuất hiện trong rất nhiều dự án Open Source.


Một Environment chỉ nên chứa rất ít code

Ví dụ:

live/production/network/main.tf

không nên dài hàng nghìn dòng.

Thay vào đó chỉ gọi module.

code
module "network" {
  source = "../../../modules/vpc"
 
  cidr = "10.0.0.0/16"
 
  environment = "production"
}

Đó gần như là tất cả.

Logic thực sự nằm trong:

modules/vpc

Điều này giúp:

  • code tái sử dụng
  • review dễ hơn
  • update ít rủi ro hơn

Variables nên nằm ở đâu?

Thông thường:

modules/

variables.tf
outputs.tf
main.tf

Còn environment sẽ truyền giá trị.

Ví dụ:

module "database" {

instance_class = "db.t4g.medium"

allocated_storage = 100

backup_retention_period = 30

}

Không hard-code bên trong module.

Module càng generic thì càng tái sử dụng được.


Một state hay nhiều state?

Đây là câu hỏi rất phổ biến.

Nhiều người mới học thường để toàn bộ infrastructure trong một state.

Everything

↓

terraform.tfstate

Điều này sẽ dẫn tới:

  • Plan rất lâu
  • Apply lâu
  • Lock toàn bộ infrastructure
  • Chỉ một thay đổi nhỏ cũng phải đọc toàn bộ state

Production thường chia thành nhiều state.

Ví dụ:

network

↓

compute

↓

database

↓

monitoring

Mỗi stack apply độc lập.

Nếu deploy ECS thì không cần lock cả VPC.


Đừng để Production phụ thuộc vào Local

Có những repository vẫn để:

terraform.tfstate

ngay trong Git repository.

Đây là điều không nên.

Production nên dùng:

  • Terraform Cloud
  • S3 Backend
  • Azure Storage
  • GCS

Remote Backend giúp:

  • Lock State
  • Version History
  • Team Collaboration
  • Backup
  • Security

State là tài sản quan trọng nhất của Terraform.

Đừng lưu nó trên máy cá nhân.


Naming Convention rất quan trọng

Ví dụ:

modules/

aws-vpc

aws-rds

aws-ecs

hoặc

modules/

network

database

compute

Quan trọng nhất là consistency.

Không nên:

vpc/

ecs/

RDS/

S3Module/

networking/

Một repository nên có một quy tắc đặt tên duy nhất.


Repository sẽ còn phát triển

Khi infrastructure lớn hơn, repository sẽ tiếp tục có thêm:

  • CI/CD
  • Policy Check
  • Security Scan
  • Cost Estimation
  • Drift Detection
  • Documentation

Nếu ngay từ đầu repository được tổ chức tốt thì việc mở rộng sau này sẽ rất đơn giản.


Một ví dụ thực tế

Repository Terraform mình đang sử dụng hiện nay có cấu trúc gần như sau:

terraform/

modules/

aws/

vercel/

cloudflare/

supabase/

live/

dev/

aws/

ap-southeast-1/

blog/

production/

aws/

ap-southeast-1/

blog/

shared/

Mỗi provider có module riêng.

Mỗi môi trường có state riêng.

Mỗi workload có configuration riêng.

Nhờ vậy việc review Pull Request hay rollback đều đơn giản hơn rất nhiều.


Những điều mình rút ra

Sau nhiều dự án, mình nhận ra:

  • Repository structure quan trọng không kém Terraform code.
  • Module nên chứa logic, environment chỉ chứa configuration.
  • Tách state theo stack sẽ giúp giảm rủi ro khi deploy.
  • Luôn dùng Remote Backend cho production.
  • Đừng tối ưu cho hôm nay, hãy tối ưu cho repository sau 2 năm nữa.

Terraform rất dễ bắt đầu.

Nhưng để repository vẫn gọn gàng sau hàng nghìn lần commit mới là điều khó.


Tổng kết

Terraform không chỉ là viết file .tf.

Một repository được thiết kế tốt sẽ giúp:

  • dễ review
  • dễ mở rộng
  • giảm xung đột khi làm việc nhóm
  • giảm thời gian deploy
  • dễ bảo trì trong nhiều năm

Đây là nền tảng để một hệ thống Infrastructure có thể phát triển bền vững.


Bài tiếp theo

Cho đến lúc này, chúng ta đều giả sử rằng toàn bộ Infrastructure đều được Terraform tạo ra ngay từ đầu.

Nhưng trong thực tế, rất nhiều công ty đã có sẵn hàng trăm tài nguyên trên AWS, Azure hay GCP trước khi quyết định sử dụng Terraform.

Vậy làm thế nào để đưa những tài nguyên đang tồn tại đó vào Terraform mà không phải xóa và tạo lại?

Chúng ta sẽ cùng tìm hiểu trong bài tiếp theo:

Import Infrastructure có sẵn vào Terraform.

Bình luận

0/2000

Đang tải bình luận…