Terraform配置GCP VPC secondary ranges出现重复键报错如何解决
解决方案
可以使用Terraform for表达式的分组模式解决该问题。分组模式通过在值表达式后添加省略号...实现,遇到重复键时会将相同键对应的所有值收集到一个列表中,而非直接抛出重复键错误。
问题根因
你当前的for表达式逻辑中,两个cluster配置的subnet_name都为default,生成map时会出现两个相同的键,Terraform默认不允许这种行为,因此触发报错。
具体实现代码
1. 基础分组写法(值为嵌套列表)
直接在原for表达式的值后添加...即可开启分组,此时同一个subnet_name对应的值为嵌套列表结构:
secondary_ranges = { for name, config in var.subnet_config : config.subnet_name => [ { range_name = local.ip_range_pods ip_cidr_range = "10.${index(keys(var.subnet_config), name)}.0.0/17" }, { range_name = local.ip_range_services ip_cidr_range = "10.${index(keys(var.subnet_config), name)}.128.0/17" } ]... }
该写法输出的结构示例如下:
{ default = [ [ # cluster1的两个secondary range { range_name = "pods", ip_cidr_range = "10.0.0.0/17" }, { range_name = "services", ip_cidr_range = "10.0.128.0/17" } ], [ # cluster2的两个secondary range { range_name = "pods", ip_cidr_range = "10.1.0.0/17" }, { range_name = "services", ip_cidr_range = "10.1.128.0/17" } ] ] }
2. 扁平化处理(适配子网模块参数要求)
GCP VPC子网模块的secondary_ranges参数要求每个子网对应一个一维的range列表,因此你需要对分组后的嵌套列表做flatten处理:
secondary_ranges = { for subnet_name, range_groups in { for name, config in var.subnet_config : config.subnet_name => [ { range_name = local.ip_range_pods ip_cidr_range = "10.${index(keys(var.subnet_config), name)}.0.0/17" }, { range_name = local.ip_range_services ip_cidr_range = "10.${index(keys(var.subnet_config), name)}.128.0/17" } ]... } : subnet_name => flatten(range_groups) }
处理后输出的结构符合模块要求:
{ default = [ { range_name = "pods", ip_cidr_range = "10.0.0.0/17" }, { range_name = "services", ip_cidr_range = "10.0.128.0/17" }, { range_name = "pods", ip_cidr_range = "10.1.0.0/17" }, { range_name = "services", ip_cidr_range = "10.1.128.0/17" } ] }
注意事项
- 你需要确认相同
subnet_name是否真的需要配置多组secondary range,避免出现同子网下CIDR重叠的问题 - 如果不同region的子网名称相同但实际是独立资源,建议调整key的生成逻辑为
${config.region}_${config.subnet_name},避免不必要的分组
内容的提问来源于stack exchange,提问作者Albert Wolchesky
相关产品推荐
相关产品推荐

