Terraform应用配置时lists参数元素类型错误问题咨询
问题根因
- 变量类型和取值逻辑不匹配:你定义的
node_hosts是两层嵌套map(map(map(object(...)))),但你在locals中遍历var.node_hosts时,直接取出的v是第二层的整组节点集合(也就是key为default对应的全部节点map),并非单个节点对象。 local.all_nodes取值逻辑错误:values(var.node_hosts)[*].name是从第一层map的value(整组节点集合)中提取不存在的name属性,返回的元素类型不是字符串,触发了join函数的类型校验报错。
你删除类型定义后Terraform会做隐式类型兼容,所以可以运行,但开启强类型校验后就会抛出错误。
修复方案
方案1:保留原有两层map结构,修正locals遍历逻辑
先拍平两层map取出所有节点对象,再做后续处理,替换你的locals块为以下内容:
locals { # 拍平两层map,提取所有节点对象 flat_nodes = flatten([ for group in values(var.node_hosts) : [ for node_key, node in group : node ] ]) all_nodes_verbose_etcd = [for node in local.flat_nodes: format("%s ip=%s etcd_instance=%s", node.name, node.ipv4_address, node.etcd_instance) if length(node.etcd_instance) > 0] all_nodes_verbose = [for node in local.flat_nodes: format("%s ip=%s", node.name, node.ipv4_address) if length(node.etcd_instance) == 0] master_nodes = [for node in local.flat_nodes: node.name if node.compute_node != true] etcd_nodes = [for node in local.flat_nodes: node.name if length(node.etcd_instance) > 0] all_nodes = [for node in local.flat_nodes : node.name] kubernetes_conf_file = format("%s/kubespray/inventory/%s/group_vars/k8s-cluster/k8s-cluster.yml", pathexpand("~"), var.kubespray_inventory) kubespray_inv_file = format("%s/kubespray/inventory/%s/inventory.ini", pathexpand("~"), var.kubespray_inventory) context_artifact = format("%s/kubespray/inventory/%s/artifacts/admin.conf", pathexpand("~"), var.kubespray_inventory) }
方案2:简化变量结构(推荐,无分组需求时使用)
如果你没有节点分组需求,只是用default做了一层无意义的嵌套,可以直接把变量改为单层map结构:
- 修改变量定义:
variable "node_hosts" { type = map(object({ name = string compute_node = bool etcd_instance = string ipv4_address = string })) }
- 对应修改tfvars配置,去掉外层的
default嵌套:
node_hosts = { z-ca-arc-control1 = { name = "z-ca-arc-control1" compute_node = false etcd_instance = "etcd1" ipv4_address = "10.123.456.01" }, z-ca-arc-control2 = { name = "z-ca-arc-control2" compute_node = false etcd_instance = "etcd2" ipv4_address = "10.123.456.02" }, z-ca-arc-compute1 = { name = "z-ca-arc-compute1" compute_node = true etcd_instance = "etcd3" ipv4_address = "10.123.456.03" }, z-ca-arc-compute2 = { name = "z-ca-arc-compute2" compute_node = true etcd_instance = "" ipv4_address = "10.123.456.04" }, z-ca-arc-compute3 = { name = "z-ca-arc-compute3" compute_node = true etcd_instance = "" ipv4_address = "10.123.456.05" } }
内容的提问来源于stack exchange,提问作者ChrisAdkin
相关产品推荐
相关产品推荐

