Terragrunt项目定制Provider:如何读取主配置公共输入?
解决Terragrunt项目级配置无法访问根配置变量的问题
核心原因
Terragrunt的include机制不会自动将父配置中的locals变量传递给子配置,仅会继承inputs、remote_state等顶层配置块的内容。你在根配置中已经将fin_config合并到inputs中,因此可以通过引用父配置的inputs来获取所需值。
直接解决方案:引用父配置的inputs
修改项目级(如project1)的terragrunt.hcl,将local.fin_config替换为include.root.inputs即可访问合并后的环境配置:
include "root" { path = find_in_parent_folders() } generate "provider" { path = "providers.tf" if_exists = "overwrite" contents = <<EOF provider "azurerm" { features {} subscription_id = "abc" skip_provider_registration = true alias = "${include.root.inputs.law}" } provider "azurerm" { features {} subscription_id = "${include.root.inputs.sub}" skip_provider_registration = true } EOF }
备选方案:抽离通用配置逻辑(避免重复代码)
如果需要在多个配置中复用环境变量计算逻辑,可将通用逻辑抽离到单独的HCL文件,再在根和项目级配置中引入:
- 创建
src/environments/common.hcl,存放通用变量计算逻辑:
locals { wrk_path = trimsuffix(path_relative_to_include(), "/") all_path = "${get_parent_terragrunt_dir()}/../environments/all" env_path = "${get_parent_terragrunt_dir()}/../environments/${local.env}" all_config = try(read_terragrunt_config("${local.all_path}/environment.hcl").inputs, {}) env_config = try(read_terragrunt_config("${local.env_path}/environment.hcl").inputs, {}) fin_config = merge(local.all_config, local.env_config) }
- 根
terragrunt.hcl中引入并使用:
include "common" { path = "${get_parent_terragrunt_dir()}/../environments/common.hcl" } remote_state { // 保持原有配置 } terraform { // 保持原有配置 extra_arguments "apply_environment" { commands = get_terraform_commands_that_need_vars() optional_var_files = [ "${include.common.locals.all_path}/${include.common.locals.wrk_path}.tfvars", "${get_parent_terragrunt_dir()}/../environments/${local.env}/${include.common.locals.wrk_path}.tfvars" ] } } inputs = include.common.locals.fin_config
- 项目级
terragrunt.hcl中引入并使用:
include "root" { path = find_in_parent_folders() } include "common" { path = "${get_parent_terragrunt_dir()}/../../environments/common.hcl" } generate "provider" { path = "providers.tf" if_exists = "overwrite" contents = <<EOF provider "azurerm" { features {} subscription_id = "abc" skip_provider_registration = true alias = "${include.common.locals.fin_config.law}" } provider "azurerm" { features {} subscription_id = "${include.common.locals.fin_config.sub}" skip_provider_registration = true } EOF }
优先推荐第一种方案,因为你已经在根配置中完成了fin_config的合并并传递到inputs,无需额外增加配置复杂度。
内容的提问来源于stack exchange,提问作者michasaucer
相关产品推荐
相关产品推荐

