如何在Terragrunt中仅当指定文件存在时引入特定Terraform模块?
可行,以下是具体实现方案
核心思路
利用Terragrunt内置的fileexists()函数检测当前工作目录下的目标文件(additional.yaml)是否存在,再通过dynamic "module"块条件性生成模块引用,仅当文件存在时才引入infrastructure/additional模块并传递变量。
具体实现步骤
- 定义本地变量判断文件状态
在Terragrunt配置文件(terragrunt.hcl)中,先通过本地变量判断文件是否存在,并读取文件内容(如果存在):
locals { # 检测当前Terragrunt工作目录下是否存在additional.yaml has_additional = fileexists("${get_terragrunt_dir()}/additional.yaml") # 读取配置文件内容,文件不存在时返回空对象 additional_config = local.has_additional ? yamldecode(file("${get_terragrunt_dir()}/additional.yaml")) : {} }
- 动态生成模块引用
使用dynamic "module"块,根据local.has_additional的值决定是否生成模块配置:
# 主模块配置(对应foo/bar模块) module "main" { source = "${dirname(dirname(dirname(get_terragrunt_dir())))}/infrastructure/${basename(get_terragrunt_dir())}" # 传递主模块所需变量 variables = { environment = "dev" config = yamldecode(file("config.yaml")) } } # 条件引入additional模块 dynamic "module" { # 仅当has_additional为true时,生成一个模块实例 for_each = local.has_additional ? [1] : [] content { source = "${dirname(dirname(dirname(get_terragrunt_dir())))}/infrastructure/additional" # 传递变量:合并additional.yaml的配置与固定变量 variables = merge( local.additional_config, { environment = "dev" component = basename(get_terragrunt_dir()) # 自动获取当前目录名(如bar) } ) } }
关键细节说明
- 路径可靠性:使用
get_terragrunt_dir()获取当前Terragrunt工作目录的绝对路径,结合dirname()和basename()函数动态计算模块源路径,避免硬编码相对路径导致的错误。 - dynamic模块的作用:Terragrunt的
module块本身不支持count或for_each参数,必须通过dynamic块实现条件性生成,这是实现需求的核心。 - 变量传递灵活性:通过
merge()函数可以将配置文件中的动态内容与固定变量结合,按需传递给additional模块。
验证方式
- 在
config/dev/foo目录执行terragrunt plan时,由于不存在additional.yaml,dynamic "module"块不会生成,只会处理主模块。 - 在
config/dev/bar目录执行terragrunt plan时,检测到additional.yaml存在,会同时处理主模块和additional模块。
内容的提问来源于stack exchange,提问作者Hendrik Wiese
相关产品推荐
相关产品推荐

