devopsdryiacInfrastructure as Codeterraformterragrunt

DRY Configuration với Terragrunt: include, generate và read_terragrunt_config

Tìm hiểu ba tính năng mạnh mẽ nhất của Terragrunt giúp loại bỏ gần như toàn bộ cấu hình lặp lại trong Terraform project: include, generate và read_terragrunt_config.

26 thg 7, 20265 min readCập nhật 26 thg 7, 2026
DRY Configuration với Terragrunt: include, generate và read_terragrunt_config

DRY Configuration với Terragrunt: include, generate và read_terragrunt_config

Trong bài trước, chúng ta đã xây dựng một repository Terragrunt theo chuẩn production.

Repository được chia thành:

  • Modules
  • Live Infrastructure
  • Environment
  • Terraform Projects

Nhưng vẫn còn một câu hỏi quan trọng:

Làm thế nào để hàng trăm Terraform project có thể chia sẻ cùng một cấu hình mà không cần copy & paste?

Đây chính là lúc Terragrunt thể hiện sức mạnh thực sự.

Ba tính năng quan trọng nhất của Terragrunt là:

  • include
  • generate
  • read_terragrunt_config

Ba tính năng này là nền tảng giúp Terragrunt loại bỏ gần như toàn bộ cấu hình bị lặp lại trong một repository lớn.


Vấn đề của Terraform

Giả sử bạn có 40 Terraform project.

Mỗi project đều cần:

  • Backend
  • Provider
  • Default Tags
  • Terraform Version
  • AWS Region
  • Common Variables

Nếu chỉ dùng Terraform, bạn sẽ viết lại:

code
terraform {
  required_version = ">= 1.10"
}

Ở project thứ hai.

Lại viết tiếp.

Project thứ ba.

Tiếp tục.

Provider cũng vậy.

code
provider "aws" {
  region = "ap-southeast-1"
 
  default_tags {
    tags = {
      ManagedBy = "Terraform"
    }
  }
}

Backend cũng vậy.

Version cũng vậy.

Sau vài tháng, repository đầy những đoạn cấu hình giống hệt nhau.

Nếu muốn đổi region?

Bạn phải sửa hàng chục file.

Đó là điều Terragrunt muốn giải quyết.


include — Kế thừa cấu hình

Đây là tính năng được sử dụng nhiều nhất.

Hãy tưởng tượng cấu trúc:

live/

terragrunt.hcl

production/

terragrunt.hcl

eks/

terragrunt.hcl

File root:

live/

terragrunt.hcl

Định nghĩa:

  • backend
  • provider
  • common locals
  • remote state
  • tags

Các project con chỉ cần:

code
include "root" {
  path = find_in_parent_folders()
}

Terragrunt sẽ tự động kế thừa toàn bộ cấu hình.

Điều này rất giống với inheritance trong lập trình hướng đối tượng.


include hoạt động như thế nào?

Giả sử:

Root

↓

Production

↓

EKS

Root chứa:

Backend
Provider
Tags

Production chứa:

Environment
AWS Account

EKS chứa:

Cluster Version
Node Size

Sau khi Terragrunt resolve toàn bộ include, EKS sẽ nhìn thấy tất cả:

Backend

+

Provider

+

Tags

+

Environment

+

Cluster Version

Mỗi tầng chỉ cần khai báo phần cấu hình thực sự khác biệt.


include không phải copy file

Điều quan trọng cần nhớ là:

Terragrunt không copy file.

Nó xây dựng một cây cấu hình.

Ví dụ:

Root

↓

Production

↓

VPC

Khi chạy:

code
terragrunt apply

Terragrunt sẽ:

  • đọc Root
  • đọc Production
  • đọc VPC
  • merge tất cả lại

Sau đó mới sinh Terraform configuration.

Điều này giúp repository luôn có một nguồn cấu hình duy nhất.


generate — Sinh Terraform Configuration

Một trong những tính năng thú vị nhất của Terragrunt là generate.

Giả sử mọi project đều cần:

code
provider "aws" {
    ...
}

Bạn hoàn toàn có thể để Terragrunt sinh file này.

Ví dụ:

provider.tf

được generate tự động.

Điều đó có nghĩa:

Trong repository, bạn sẽ không còn nhìn thấy provider nữa.

Terragrunt sẽ tạo nó trước khi Terraform chạy.

Điều này thường được dùng cho:

  • provider
  • backend
  • versions.tf
  • provider aliases
  • common Terraform settings

Vì sao generate hữu ích?

Giả sử công ty quyết định:

Chuyển toàn bộ provider sang AWS Provider phiên bản mới.

Nếu dùng Terraform thuần:

Bạn sửa hàng trăm file.

Nếu dùng Terragrunt:

Bạn sửa đúng một nơi.

Lần chạy tiếp theo, tất cả project đều nhận được provider mới.

Đây chính là sức mạnh của việc sinh cấu hình.


read_terragrunt_config

Đây là tính năng ít được nhắc tới hơn.

Nhưng cực kỳ hữu ích.

Giả sử bạn có:

account.hcl

Chứa:

  • Account ID
  • Region
  • Common Tags

Một project khác có thể đọc:

account.hcl

và sử dụng toàn bộ giá trị bên trong.

Điều này giúp chia sẻ configuration giữa nhiều project mà không cần duplication.


Cấu hình theo từng tầng

Một repository Terragrunt thường được chia thành nhiều tầng.

Ví dụ:

Root

Chứa:

  • backend
  • provider
  • common locals

Production

Chứa:

  • account
  • region
  • environment

Application

Chứa:

  • application name
  • common variables

EKS

Chứa:

  • cluster version
  • instance types

Nhờ đó, mỗi tầng chỉ chịu trách nhiệm cho đúng phạm vi của mình.

Đây là một nguyên tắc rất quan trọng khi thiết kế repository.


Một project chỉ còn vài dòng

Sau khi tận dụng ba tính năng trên, một project Terragrunt có thể chỉ còn:

code
include "root" {
  path = find_in_parent_folders()
}
 
terraform {
  source = "../../../modules/eks"
}
 
inputs = {
  cluster_name = "production"
}

Đó gần như là toàn bộ cấu hình.

Không còn:

  • backend
  • provider
  • version
  • remote state
  • default tags

Mọi thứ đều được kế thừa hoặc generate tự động.


Đây mới là DRY thực sự

Nhiều người nghĩ DRY chỉ là dùng Terraform Module.

Thực tế:

Terraform Module chỉ giúp tái sử dụng resource.

Terragrunt giúp tái sử dụng:

  • configuration
  • repository structure
  • backend
  • provider
  • variables
  • environment settings

Hai công cụ giải quyết hai bài toán hoàn toàn khác nhau.


Có nên lạm dụng include?

Không.

Một repository có thể có:

Root

↓

Organization

↓

Production

↓

Application

↓

Service

Nếu kế thừa quá nhiều tầng, việc tìm nguồn gốc của một biến sẽ trở nên khó khăn.

Nguyên tắc chung là:

  • Chia tầng hợp lý.
  • Không tạo hierarchy quá sâu.
  • Mỗi tầng chỉ chứa đúng trách nhiệm của nó.

Repository sẽ dễ hiểu hơn rất nhiều.


Tổng kết

Ba tính năng:

  • include
  • generate
  • read_terragrunt_config

chính là "linh hồn" của Terragrunt.

Chúng giúp:

  • Loại bỏ phần lớn cấu hình lặp lại.
  • Chuẩn hóa repository.
  • Quản lý hàng trăm Terraform project.
  • Chia sẻ configuration giữa nhiều environment.
  • Dễ bảo trì và mở rộng trong thời gian dài.

Nếu chỉ học một phần của Terragrunt, thì đây chính là phần quan trọng nhất.


Bài tiếp theo

Ở bài tiếp theo, chúng ta sẽ tìm hiểu Dependency Management trong Terragrunt, cách Terragrunt tự động xây dựng dependency graph giữa các Terraform project và giúp chúng được triển khai theo đúng thứ tự mà không cần ghi nhớ hay thực hiện thủ công.

Bình luận

0/2000

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

Trung Nguyen

Trung Nguyen

Software engineer xây dựng các hệ thống đơn giản, đáng tin cậy. Mình viết về kiến trúc, Java và những gì mình học được trên chặng đường.

Xem thêm về mình