Terragrunt Generator 综合工具包,用于生成遵循当前标准和约定的最佳实践Terragrunt配置(HCL文件)。在创建新的Terragrunt资源(根配置、子模块、堆栈、环境设置)或构建多环境Terragrunt项目时,请使用此技能。
Terragrunt生成器
概览
生成遵循当前最佳实践、命名约定和安全标准的生产就绪Terragrunt配置。所有生成的配置都会自动验证。
支持的Terragrunt 2025功能:
- 堆栈 - 带有
terragrunt.stack.hcl的基础设施蓝图(自v0.78.0起正式发布) - 特性标志 - 通过
feature块进行运行时控制 - 排除块 - 细粒度执行控制(替换已弃用的
skip) - 错误块 - 高级错误处理(替换已弃用的
retryable_errors) - OpenTofu引擎 - 替代IaC引擎支持
根配置命名
推荐:根据迁移指南,使用
root.hcl代替terragrunt.hcl作为根文件。
| 方法 | 根文件 | 包含语法 |
|---|---|---|
| 现代 | root.hcl |
find_in_parent_folders("root.hcl") |
| 传统 | terragrunt.hcl |
find_in_parent_folders() |
架构模式
关键:在生成任何配置之前,必须确定架构模式并理解其约束。
模式A:多环境与环境不可知根
使用场景:管理多个环境(开发/测试/生产)并共享根配置。
关键原则:root.hcl是环境不可知的 - 它不读取环境特定文件。
infrastructure/
├── root.hcl # 环境不可知(不引用env.hcl)
├── dev/
│ ├── env.hcl # 环境变量(locals块)
│ ├── vpc/terragrunt.hcl
│ └── rds/terragrunt.hcl
└── prod/
├── env.hcl # 环境变量(locals块)
├── vpc/terragrunt.hcl
└── rds/terragrunt.hcl
Root.hcl约束:
- ❌ 不能使用
read_terragrunt_config(find_in_parent_folders("env.hcl"))- 根级别不存在env.hcl - ❌ 不能引用来自env.hcl的
local.environment或local.aws_region - ✅ 可以使用静态值或
get_env()进行运行时配置 - ✅ 可以使用
${path_relative_to_include()}用于状态键(这可以动态工作)
子模块读取env.hcl:
# dev/vpc/terragrunt.hcl
include "root" {
path = find_in_parent_folders("root.hcl")
}
locals {
env = read_terragrunt_config(find_in_parent_folders("env.hcl"))
}
inputs = {
name = "${local.env.locals.environment}-vpc" # 有效:dev/中存在env.hcl
}
模式B:单环境或环境感知根
使用场景:单环境或所有环境共享相同的根并进行环境检测。
infrastructure/
├── root.hcl # 可以通过get_env()或目录解析进行环境感知
├── account.hcl # 账户级配置(可选)
├── region.hcl # 区域级配置(可选)
└── vpc/
└── terragrunt.hcl
Root.hcl可以检测环境:
# root.hcl - 通过目录路径检测环境
locals {
# 从路径解析环境(例如,"prod/vpc" -> "prod")
path_parts = split("/", path_relative_to_include())
environment = local.path_parts[0]
# 或者使用环境变量
environment = get_env("TG_ENVIRONMENT", "dev")
}
模式C:共享环境变量(_env目录)
使用场景:通过符号链接或直接引用集中环境变量。
infrastructure/
├── root.hcl # 环境不可知
├── _env/ # 集中化的环境定义
│ ├── prod.hcl
│ ├── staging.hcl
│ └── dev.hcl
├── prod/
│ ├── env.hcl # 从_env/prod.hcl读取
│ └── vpc/terragrunt.hcl
└── dev/
├── env.hcl # 从_env/dev.hcl读取
└── vpc/terragrunt.hcl
env.hcl从_env读取:
# prod/env.hcl
locals {
env_vars = read_terragrunt_config("${get_repo_root()}/_env/prod.hcl")
# 重新导出给子模块
environment = local.env_vars.locals.environment
aws_region = local.env_vars.locals.aws_region
vpc_cidr = local.env_vars.locals.vpc_cidr
# ... 其他变量
}
生成前模式检查表
强制:在写任何文件之前,你必须完成此检查表并将其输出给用户,填写检查标记。这不是可选的。
在生成任何文件之前输出此完成的检查表:
## 架构模式选择
[x] 确定架构模式:模式___(A/B/C)
[x] Root.hcl范围:[ ] 环境不可知 或 [ ] 环境感知
[x] env.hcl位置:_________________
[x] 子模块通过以下方式访问env:_________________
[x] 验证:没有文件引用其位置不存在的路径
示例完成的检查表:
## 架构模式选择
[x] 确定架构模式:模式A(多环境与环境不可知根)
[x] Root.hcl范围:[x] 环境不可知 或 [ ] 环境感知
[x] env.hcl位置:dev/env.hcl, prod/env.hcl(每个环境一个)
[x] 子模块通过以下方式访问env:read_terragrunt_config(find_in_parent_folders("env.hcl"))
[x] 验证:没有文件引用其位置不存在的路径
使用场景
- 创建新的Terragrunt项目或配置
- 设置多环境基础设施(开发/测试/生产)
- 实施DRY Terraform配置
- 管理具有依赖关系的复杂基础设施
- 使用自定义Terraform提供程序或模块
核心能力
1. 生成根配置
创建带有远程状态、提供程序配置和公共变量的根级root.hcl或terragrunt.hcl。
强制:在生成之前,阅读模板文件:
阅读:assets/templates/root/terragrunt.hcl
模板:assets/templates/root/terragrunt.hcl
模式:references/common-patterns.md → 根配置模式
关键占位符替换:
[BUCKET_NAME],[AWS_REGION],[DYNAMODB_TABLE][TERRAFORM_VERSION],[PROVIDER_NAME],[PROVIDER_VERSION][ENVIRONMENT],[PROJECT_NAME]
Root.hcl设计原则:
- 默认环境不可知 - 不要假设根级别存在env.hcl
- 使用静态值提供/后端区域 - 或使用
get_env()进行运行时配置 - 状态键使用
path_relative_to_include()- 这自动包括环境路径 - 提供程序标签可以是静态的 - 环境特定的标签放在子模块中
2. 生成子模块配置
创建具有依赖关系、模拟输出和正确包含的子模块。
强制:在生成之前,阅读模板文件:
阅读:assets/templates/child/terragrunt.hcl
模板:assets/templates/child/terragrunt.hcl
模式:references/common-patterns.md → 子模块模式
模块源选项:
- 本地:
"../../modules/vpc" - Git:
"git::https://github.com/org/repo.git//path?ref=v1.0.0" - 注册表:
"tfr:///terraform-aws-modules/vpc/aws?version=5.1.0"
3. 生成独立模块
不依赖根的自包含模块。
强制:在生成之前,阅读模板文件:
阅读:assets/templates/module/terragrunt.hcl
模板:assets/templates/module/terragrunt.hcl
4. 生成多环境基础设施
为开发/测试/生产完成目录结构。
强制:在生成之前:
- 确定架构模式(见架构模式部分)
- 阅读根和子模块的相关模板
- 验证env.hcl放置和访问模式
模式:references/common-patterns.md → 环境特定模式
典型结构(模式A - 环境不可知根):
infrastructure/
├── root.hcl # 环境不可知根配置
├── dev/
│ ├── env.hcl # 开发环境变量
│ └── vpc/terragrunt.hcl
└── prod/
├── env.hcl # 生产环境变量
└── vpc/terragrunt.hcl
5. 生成Terragrunt堆栈(2025)
使用terragrunt.stack.hcl的基础设施蓝图。
强制:在生成之前,阅读模板文件:
阅读:assets/templates/stack/terragrunt.stack.hcl 阅读:assets/templates/catalog/terragrunt.hcl
文档:堆栈文档
模板:assets/templates/stack/terragrunt.stack.hcl
目录模板:assets/templates/catalog/terragrunt.hcl
模式:references/common-patterns.md → 堆栈模式
命令:
terragrunt stack generate # 生成单元配置
terragrunt stack run plan # 计划所有单元
terragrunt stack run apply # 应用所有单元
terragrunt stack output # 获取聚合输出
terragrunt stack clean # 清理生成的目录
6. 生成特性标志(2025)
无需代码更改即可进行运行时控制。
文档:特性标志文档
模式:references/common-patterns.md → 特性标志模式
关键:特性标志
default值必须是静态的(布尔值、字符串、数字)。 它们不能引用local.*值。使用静态默认值并通过CLI/env变量覆盖。
正确:
feature "enable_monitoring" {
default = false # 静态值 - 可以
}
错误:
feature "enable_monitoring" {
default = local.env.locals.enable_monitoring # 动态引用 - 失败
}
用法:
terragrunt apply --feature enable_monitoring=true
# 或
export TG_FEATURE="enable_monitoring=true"
环境特定默认值:每个环境文件使用不同的静态默认值,而不是动态引用。
7. 生成排除块(2025)
细粒度执行控制(替换已弃用的skip)。
文档:排除块参考
模式:references/common-patterns.md → 排除块模式
动作:"plan", "apply", "destroy", "all", "all_except_output"
生产推荐:对于关键生产资源,添加排除块以防止意外销毁:
# 防止意外销毁生产数据库
exclude {
if = true
actions = ["destroy"]
exclude_dependencies = false
}
# 对于关键资源也使用prevent_destroy
prevent_destroy = true
8. 生成错误块(2025)
高级错误处理(替换已弃用的retryable_errors)。
文档:错误块参考
模式:references/common-patterns.md → 错误块模式
9. 生成OpenTofu引擎配置(2025)
使用OpenTofu作为IaC引擎。
文档:引擎文档
模式:references/common-patterns.md → OpenTofu引擎模式
10. 处理自定义提供程序/模块
在生成具有自定义提供程序的配置时:
- 识别提供程序名称、源和版本
- 搜索使用WebSearch:
"[provider] terraform provider [version] documentation" - 或使用Context7 MCP如果可用,提供结构化文档
- 生成具有适当的
required_providers块 - 记录认证要求在注释中
生成工作流
关键:对于每个生成任务,都必须遵循此工作流。跳过步骤会导致验证错误。
第1步:理解需求
- 什么类型的配置?(根、子模块、独立、堆栈)
- 单环境还是多环境?
- 模块之间存在哪些依赖关系?
- 将使用哪些提供程序/模块?
第2步:确定架构模式
强制:在编写任何文件之前选择并记录模式。
| 场景 | 模式 | Root.hcl范围 |
|---|---|---|
| 多环境共享根 | 模式A | 环境不可知 |
| 单环境 | 模式B | 环境感知 |
| 集中化环境变量 | 模式C | 环境不可知 |
验证:
[ ] 已识别模式:___
[ ] Root.hcl将是:[ ] 环境不可知 [ ] 环境感知
[ ] env.hcl将位于:___
[ ] 子模块将通过以下方式读取env.hcl:___
第3步:阅读所需模板
强制:在生成每种配置类型之前阅读相关模板文件。
| 配置类型 | 要阅读的模板 |
|---|---|
| 根配置 | assets/templates/root/terragrunt.hcl |
| 子模块 | assets/templates/child/terragrunt.hcl |
| 独立模块 | assets/templates/module/terragrunt.hcl |
| 堆栈文件 | assets/templates/stack/terragrunt.stack.hcl |
| 目录单元 | assets/templates/catalog/terragrunt.hcl |
还要阅读:
references/common-patterns.md- 生成模式的主要来源
第4步:生成并验证
验证策略:在生成过程中使用组合的内联检查和最后批量验证。
多环境项目的生成顺序:
-
首先生成root.hcl
- 内联检查(生成过程中):
- [ ] 如果环境不可知,则没有
read_terragrunt_config(find_in_parent_folders("env.hcl")) - [ ]
remote_state块有encrypt = true - [ ] 使用
errors块(而不是弃用的retryable_errors)
- [ ] 如果环境不可知,则没有
- 内联检查(生成过程中):
-
为每个环境生成env.hcl文件
- 内联检查(生成过程中):
- [ ]
locals块包含环境、aws_region和模块特定变量 - [ ] 没有引用在该目录级别不存在的文件
- [ ]
- 内联检查(生成过程中):
-
生成子模块(VPC等)-首先生成没有依赖关系的模块
- 内联检查(生成过程中):
- [ ]
include块使用find_in_parent_folders("root.hcl") - [ ] 存在
read_terragrunt_config(find_in_parent_folders("env.hcl")) - [ ]
terraform.source使用有效语法(tfr:///, git::, 或相对路径)
- [ ]
- 内联检查(生成过程中):
-
生成依赖模块(RDS, EKS等)
- 内联检查(生成过程中):
- [ ]
dependency块有mock_outputs - [ ]
mock_outputs_allowed_terraform_commands包括["validate", "plan", "destroy"] - [ ] 生产模块有
prevent_destroy = true和/或exclude块
- [ ]
- 内联检查(生成过程中):
-
在所有文件生成后运行批量验证
注意:完整的CLI验证(
terragrunt hcl fmt,terragrunt dag graph)需要所有文件存在,因此这些在最后批量进行。# 批量验证命令(所有文件存在后运行): terragrunt hcl fmt --check # 格式验证 terragrunt dag graph # 依赖图验证- 调用
devops-skills:terragrunt-validator技能进行全面验证
- 调用
第5步:修复并重新验证
如果验证失败:
- 分析错误(路径解析、缺少变量、语法错误)
- 在特定文件中修复问题
- 重新验证修复的文件
- 重复直到所有错误都解决
第6步:展示结果
按照下面的"展示要求"部分进行。
验证工作流
关键:每个生成的配置都必须经过验证。
增量验证检查
生成root.hcl后:
cd <infrastructure-directory>
terragrunt hcl fmt --check
生成每个子模块后:
cd <module-directory>
terragrunt hcl fmt --check
# 如果没有依赖其他模块:
terragrunt hcl validate --inputs
全面验证
所有文件生成后:
-
调用验证技能:
调用:devops-skills:terragrunt-validator技能 -
如果验证失败:
- 分析错误(缺少占位符、无效语法、错误路径)
- 修复问题
- 重新验证(重复直到所有错误都解决)
-
如果验证成功:展示配置和使用说明
仅在以下情况下跳过验证:部分片段、文档示例或用户明确请求
展示要求
强制:验证成功后,你必须展示以下所有部分。不完整的展示是不可接受的。复制并填写下面的模板。
1. 目录结构总结(强制)
# 显示生成的结构
tree <infrastructure-directory>
2. 生成的文件(强制)
输出此表,列出所有生成的文件:
| 文件 | 目的 |
|------|---------|
| root.hcl | 所有子模块的共享配置(状态后端、提供程序) |
| dev/env.hcl | 开发环境变量 |
| prod/env.hcl | 生产环境变量 |
| dev/vpc/terragrunt.hcl | 开发环境的VPC模块 |
| ... | ... |
3. 使用说明(强制)
**你必须包括此部分。**复制下面的模板并填写实际值:
## 使用说明
### 先决条件
在运行Terragrunt命令之前,请确保:
1. AWS凭据已配置(`aws configure`或环境变量)
2. S3存储桶`<BUCKET_NAME>`存在以存储状态
3. DynamoDB表`<TABLE_NAME>`存在以进行状态锁定
### 命令
# 导航到基础设施目录
cd <INFRASTRUCTURE_DIR>
# 初始化所有模块
terragrunt run --all init
# 预览特定环境的更改
cd <ENV>/vpc && terragrunt plan
# 预览所有更改
terragrunt run --all plan
# 应用更改(需要批准)
terragrunt run --all apply
# 销毁(请格外小心)
terragrunt run --all destroy
4. 环境特定说明(强制)
**你必须包括此部分。**复制下面的模板并填写实际值:
## 环境说明
### 必需的环境变量
| 变量 | 描述 | 示例 |
|----------|-------------|---------|
| AWS_PROFILE | 要使用的AWS CLI配置文件 | `my-profile` |
| AWS_REGION | AWS区域(或在提供程序中设置) | `us-east-1` |
### 先决条件
- [ ] 存储桶`<BUCKET_NAME>`必须在首次运行前存在
- [ ] DynamoDB表`<TABLE_NAME>`必须存在以进行状态锁定
- [ ] Terraform状态管理的IAM权限
### 生产特定保护
| 模块 | 保护 | 描述 |
|--------|------------|-------------|
| prod/rds | `prevent_destroy = true` | 防止意外删除数据库 |
| prod/rds | `exclude { actions = ["destroy"] }` | 阻止销毁命令 |
5. 下一步(可选)
建议用户接下来可能想要做的事情(添加更多模块、自定义配置等)
最佳实践
参考../devops-skills:terragrunt-validator/references/best_practices.md以获得全面的指导方针。
关键原则:
- 使用
include块继承根配置(DRY) - 始终为依赖项提供模拟输出
- 启用状态加密(
encrypt = true) - 使用
generate块进行提供程序配置 - 指定有界版本约束(
~> 5.0,而不是>= 5.0)用于本地/Git模块 - 永远不要硬编码凭据或秘密
- 为瞬态错误配置重试逻辑
注意有关注册表模块的版本约束:当使用Terraform注册表模块(例如
tfr:///terraform-aws-modules/vpc/aws?version=5.1.0)时,它们通常定义自己的required_providers。在这种情况下,你可以省略在root.hcl中生成required_providers以避免冲突。模块的固定版本(?version=X.X.X)提供版本约束。有关详细信息,请参阅"常见问题 → 注册表模块与提供程序冲突"。
要避免的反模式:
- 硬编码的账户ID、区域或环境名称
- 缺少依赖项的模拟输出
- 跨模块重复的配置
- 未加密的状态存储
- 缺少或宽松的版本约束(使用定义自己版本的注册表模块时除外)
- Root.hcl尝试读取根级别不存在的env.hcl
弃用的属性
| 弃用 | 替换 | 参考 |
|---|---|---|
skip |
exclude块 |
文档 |
retryable_errors |
errors.retry块 |
文档 |
run-all |
run --all |
迁移 |
--terragrunt-*标志 |
无前缀标志 | CLI参考 |
TERRAGRUNT_*环境变量 |
TG_*环境变量 |
CLI参考 |
资源
模板 - 生成前必须阅读
| 配置类型 | 模板文件 | 何时阅读 |
|---|---|---|
| 根配置 | assets/templates/root/terragrunt.hcl |
生成任何root.hcl之前 |
| 子模块 | assets/templates/child/terragrunt.hcl |
生成任何子模块之前 |
| 独立模块 | assets/templates/module/terragrunt.hcl |
生成独立模块之前 |
| 堆栈文件 | assets/templates/stack/terragrunt.stack.hcl |
生成堆栈之前 |
| 目录单元 | assets/templates/catalog/terragrunt.hcl |
生成目录单元之前 |
参考
| 参考 | 内容 | 何时阅读 |
|---|---|---|
references/common-patterns.md |
所有生成模式,含示例 | 总是,在生成之前 |
../devops-skills:terragrunt-validator/references/best_practices.md |
综合最佳实践 | 总是,在生成之前 |
官方文档
常见问题
Root.hcl找不到env.hcl
症状:
错误:尝试从null值获取属性
在./root.hcl第X行:
这个值是null,所以它没有任何属性。
原因:Root.hcl尝试通过find_in_parent_folders("env.hcl")读取env.hcl,但根级别不存在env.hcl。
解决方案:使root.hcl环境不可知:
# 多环境设置中不要在root.hcl中这样做:
locals {
env_vars = read_terragrunt_config(find_in_parent_folders("env.hcl")) # 失败
}
# 使用静态值或get_env():
generate "provider" {
path = "provider.tf"
if_exists = "overwrite_terragrunt"
contents = <<EOF
provider "aws" {
region = "us-east-1" # 静态值,或使用get_env("AWS_REGION", "us-east-1")
}
EOF
}
注册表模块与提供程序冲突
当使用Terraform注册表模块(例如tfr:///terraform-aws-modules/vpc/aws)时,它们可能定义自己的required_providers块。这可能与root.hcl生成的提供程序配置冲突。
症状:
错误:重复的必需提供程序配置
解决方案:
-
删除冲突的生成块 - 如果使用管理自己的提供程序的注册表模块,避免生成重复的
required_providers:# 在root.hcl中 - 仅生成提供程序配置,而不是required_providers generate "provider" { path = "provider.tf" if_exists = "overwrite_terragrunt" contents = <<EOF provider "aws" { region = "us-east-1" } EOF } -
使用if_exists = “skip” - 如果文件已存在则跳过生成:
generate "versions" { path = "versions.tf" if_exists = "skip" # 不要覆盖模块的versions.tf contents = "..." } -
清除缓存 - 如果修复后冲突仍然存在:
rm -rf .terragrunt-cache terragrunt init
特性标志验证错误
如果你看到Unknown variable; There is no variable named "local"在特性块中,确保默认值是静态值(见特性标志部分)。
子模块找不到env.hcl
症状:
错误:尝试从null值获取属性
在./dev/vpc/terragrunt.hcl第X行:
原因:子模块的find_in_parent_folders("env.hcl")找不到env.hcl。
解决方案:确保env.hcl存在于环境目录中:
dev/
├── env.hcl # 此文件必须存在
└── vpc/
└── terragrunt.hcl # 调用find_in_parent_folders("env.hcl")
快速参考卡
文件阅读检查表
生成前按顺序阅读这些文件:
- [ ]
references/common-patterns.md- 了解可用模式 - [ ]
../devops-skills:terragrunt-validator/references/best_practices.md- 了解规则 - [ ] 相关模板(s)从
assets/templates/- 结构参考
架构决策树
Q:多个环境(开发/测试/生产)?
├─ 是 → Q:共享根配置?
│ ├─ 是 → 模式A:环境不可知根
│ └─ 否 → 每个环境一个单独的root.hcl
└─ 否 → Q:需要环境检测?
├─ 是 → 模式B:环境感知根
└─ 否 → 模式B:简单的单环境
验证序列
- 格式检查:
terragrunt hcl fmt --check - 输入验证:
terragrunt hcl validate --inputs - 全面验证:调用
devops-skills:terragrunt-validator技能 - 修复错误 → 重新验证 → 重复直到清理