Terraform 0.11升0.12:列表变量类型不兼容问题求助
问题分析
你遇到的错误核心是变量类型定义和实际默认值的结构不匹配:
Error: Invalid default value for variable
...
This default value is not compatible with the variable's type constraint: element 0: string required.
你把master_authorized_networks_config定义成了list(string)(字符串列表),但你的默认值却是一个包含嵌套对象的复杂结构——外层是列表,里面是带cidr_blocks字段的对象,而cidr_blocks又包含多个带cidr_block和display_name的对象。Terraform期望每个列表元素都是字符串,自然会抛出类型不匹配的错误。
解决方案:修正变量类型约束
你需要把变量类型改成和默认值结构完全匹配的嵌套类型。在Terraform 0.12+中,我们可以用list+object的组合来定义这种复杂结构:
variable "master_authorized_networks_config" { type = list(object({ cidr_blocks = list(object({ cidr_block = string display_name = string })) })) description = "The list of CIDR blocks of master authorized networks." default = [ { cidr_blocks = [ { cidr_block = "XXXXXX/32" display_name = "XXXXX" }, { cidr_block = "XXXXXX/32" display_name = "XXXXX" }, { cidr_block = "XXXXXX/32" display_name = "XXXXX" }, { cidr_block = "XXXXXX/32" display_name = "XXXXX" }, ] }, ] }
这个定义明确告诉Terraform:
master_authorized_networks_config是一个列表- 列表中的每个元素是一个对象,包含
cidr_blocks字段 cidr_blocks又是一个列表,每个元素是包含cidr_block(字符串)和display_name(字符串)的对象
这样就和你提供的默认值结构完全对齐了,执行terraform apply时就不会再报错。
可选简化:如果外层列表仅需一个元素
观察你的默认值,外层列表只有一个元素。如果你的业务场景中这个变量永远只需要一组cidr_blocks,可以去掉外层的list,直接定义为object类型:
variable "master_authorized_networks_config" { type = object({ cidr_blocks = list(object({ cidr_block = string display_name = string })) }) description = "The CIDR blocks of master authorized networks." default = { cidr_blocks = [ { cidr_block = "XXXXXX/32" display_name = "XXXXX" }, { cidr_block = "XXXXXX/32" display_name = "XXXXX" }, { cidr_block = "XXXXXX/32" display_name = "XXXXX" }, { cidr_block = "XXXXXX/32" display_name = "XXXXX" }, ] } }
注意:使用这个简化版本时,你传入模块的方式不需要改变(依然是master_authorized_networks_config = var.master_authorized_networks_config),但要确保模块内部对该变量的访问逻辑也对应调整(比如不再按列表索引访问,直接访问对象字段)。
内容的提问来源于stack exchange,提问作者debek

