Cấu trúc Repository Production với Terragrunt
Ở những bài trước, chúng ta đã dành nhiều thời gian để hiểu Terraform là gì và vì sao Terragrunt ra đời.
Terraform rất giỏi trong việc quản lý infrastructure.
Nhưng khi số lượng Terraform project tăng lên, việc tổ chức repository, tái sử dụng cấu hình và quản lý dependency trở nên ngày càng khó khăn.
Terragrunt không chỉ giúp giảm việc copy & paste.
Điều quan trọng hơn là nó mang đến một cách tổ chức repository thống nhất, giúp cả team có thể mở rộng hạ tầng trong nhiều năm mà không biến repository thành một "mê cung".
Trong bài viết này, chúng ta sẽ xây dựng tư duy để thiết kế một repository Terragrunt theo chuẩn production.
Bài toán của một repository lớn
Hãy tưởng tượng công ty của bạn có:
- 4 môi trường
- 5 AWS Account
- 60 Terraform modules
Chỉ riêng production đã có:
VPC
EKS
IAM
RDS
Redis
CloudFront
S3
ALB
Monitoring
Logging
Secrets
...
Nếu mỗi module là một Terraform project độc lập thì rất nhanh bạn sẽ có hơn một trăm project.
Lúc này, repository không còn đơn giản nữa.
Bạn cần trả lời rất nhiều câu hỏi:
- Module nằm ở đâu?
- Environment nằm ở đâu?
- Production khác Development như thế nào?
- Shared infrastructure để ở đâu?
- Team mới vào sẽ chạy project nào trước?
- Làm sao để mọi repository đều giống nhau?
Đây mới chính là bài toán lớn nhất của Infrastructure as Code.
Cách tổ chức mà nhiều người mới thường làm
Repository thường bắt đầu như thế này:
terraform/
vpc/
eks/
rds/
redis/
Ban đầu mọi thứ đều ổn.
Sau đó cần thêm môi trường.
terraform/
dev-vpc/
prod-vpc/
staging-vpc/
dev-rds/
prod-rds/
dev-eks/
prod-eks/
Sau vài tháng:
terraform/
dev-vpc
prod-vpc
uat-vpc
sandbox-vpc
dev-rds
prod-rds
uat-rds
dev-redis
prod-redis
dev-monitoring
prod-monitoring
...
Repository bắt đầu trở nên lộn xộn.
Tên thư mục không còn thống nhất.
Không biết project nào dùng module nào.
Không biết environment nào đang deploy account nào.
Đây là dấu hiệu cho thấy repository cần được tổ chức lại.
Tách Module và Live Infrastructure
Một trong những nguyên tắc quan trọng nhất của Terragrunt là:
Module và Infrastructure đang chạy là hai thứ hoàn toàn khác nhau.
Module chỉ mô tả cách tạo resource.
Ví dụ:
modules/
vpc/
eks/
rds/
redis/
Module không biết:
- đang deploy môi trường nào
- account nào
- region nào
- backend nào
Nó chỉ đơn thuần định nghĩa infrastructure.
Ngược lại, phần triển khai thực tế sẽ nằm ở repository khác hoặc thư mục khác.
Ví dụ:
live/
dev/
production/
Đây là nơi Terragrunt phát huy sức mạnh.
Repository chuẩn của Terragrunt
Một cấu trúc phổ biến sẽ như sau:
infrastructure/
├── modules/
│
│ ├── vpc/
│ ├── eks/
│ ├── rds/
│ ├── redis/
│ └── ...
│
└── live/
├── dev/
├── staging/
└── production/
Trong đó:
modules
Chứa Terraform Modules.
Không chứa state.
Không chứa backend.
Không chứa thông tin của environment.
Chỉ là các module có thể tái sử dụng.
live
Đây là nơi deploy thực tế.
Mỗi thư mục tương ứng với một môi trường.
Ví dụ:
live/
dev/
staging/
production/
Mỗi environment sẽ sử dụng lại các module bên trên.
Đây chính là điểm khác biệt lớn so với việc copy cả project Terraform.
Bên trong một Environment
Ví dụ thư mục Production:
production/
vpc/
eks/
rds/
redis/
network/
dns/
Mỗi thư mục chỉ đại diện cho một Terraform project.
Ví dụ:
production/
vpc/
Bên trong gần như chỉ còn:
terragrunt.hcl
Không có hàng trăm dòng Terraform.
Không có backend.
Không có provider.
Không có biến bị lặp lại.
Tất cả sẽ được Terragrunt tự động sinh ra.
Đó là lý do repository trở nên cực kỳ gọn gàng.
Thêm nhiều AWS Account
Repository cũng có thể mở rộng theo Account.
Ví dụ:
live/
aws/
development/
staging/
production/
azure/
development/
production/
Hoặc:
live/
shared/
production/
network/
application/
production/
platform/
production/
Việc chia theo Account hay Business Unit hoàn toàn linh hoạt.
Điều quan trọng là toàn bộ cấu trúc luôn thống nhất.
Phân tầng Configuration
Một trong những triết lý quan trọng của Terragrunt là:
Configuration càng dùng chung thì càng đặt lên cao.
Ví dụ:
Root
↓
Production
↓
VPC
Thông tin chung nhất:
- Terraform version
- Provider version
- Backend
- Default Tags
được đặt ở tầng trên.
Thông tin chỉ dành riêng cho Production sẽ đặt ở tầng dưới.
Thông tin chỉ dành riêng cho VPC sẽ đặt ở thư mục VPC.
Nhờ vậy, cùng một cấu hình sẽ không phải viết lại hàng chục lần.
Ở bài tiếp theo, chúng ta sẽ tìm hiểu cơ chế include, chính là tính năng giúp Terragrunt kế thừa cấu hình theo mô hình này.
Một project Terragrunt trông nhỏ đến bất ngờ
Ví dụ:
production/
eks/
terragrunt.hcl
Có thể chỉ chứa vài dòng cấu hình.
Toàn bộ:
- backend
- provider
- remote state
- variables
- tags
đều được kế thừa từ các tầng phía trên.
Điều này khiến repository rất dễ đọc.
Khi mở một project, bạn chỉ nhìn thấy phần cấu hình thực sự khác biệt.
Vì sao cấu trúc này mở rộng tốt?
Giả sử hôm nay bạn có:
10 projects
Một năm sau:
80 projects
Hai năm sau:
250 projects
Nếu repository được tổ chức tốt ngay từ đầu thì gần như không cần thay đổi kiến trúc.
Bạn chỉ tiếp tục thêm:
production/
new-service/
Hoặc:
staging/
new-service/
Mọi thứ còn lại đều đã được kế thừa.
Đây chính là lý do rất nhiều công ty có thể quản lý hàng trăm Terraform project trong cùng một repository.
Repository không chỉ dành cho máy
Nhiều người nghĩ:
Repository chỉ cần Terraform đọc được là đủ.
Thực tế không phải vậy.
Repository còn phải phục vụ:
- Developer
- DevOps Engineer
- SRE
- Platform Team
- Security Team
- Người mới onboard
Một cấu trúc rõ ràng giúp mọi người có thể nhanh chóng trả lời những câu hỏi như:
- Infrastructure này thuộc môi trường nào?
- Module này được dùng ở đâu?
- Project này deploy vào account nào?
- Nếu cần thêm một service mới thì đặt ở đâu?
Đó là lý do repository structure luôn được xem là một phần của kiến trúc hệ thống, chứ không đơn thuần là cách sắp xếp thư mục.
Tổng kết
Một repository Terragrunt tốt không phải là repository có nhiều thư mục.
Mà là repository có quy tắc rõ ràng.
Điểm quan trọng nhất cần nhớ là:
- Terraform Modules và Live Infrastructure nên được tách riêng.
- Mỗi Terraform project nên thật nhỏ.
- Mỗi Environment chỉ chứa phần cấu hình khác biệt.
- Những cấu hình dùng chung nên được đặt ở cấp cao hơn.
- Repository cần được thiết kế để mở rộng trong nhiều năm, chứ không chỉ cho dự án hiện tại.
Đây chính là nền tảng để tận dụng toàn bộ sức mạnh của Terragrunt.
Bài tiếp theo
Ở bài tiếp theo, chúng ta sẽ tìm hiểu tính năng quan trọng nhất của Terragrunt: DRY Configuration với include, generate và read_terragrunt_config, cơ chế giúp loại bỏ gần như toàn bộ phần cấu hình bị lặp lại trong các Terraform project.
