terraform - “列表”参数的值无效:列表元素类型不正确:需要字符串
问题描述
应用配置时出现以下错误:
Error: Invalid function argument
│
│ on modules/kubernetes_cluster/main.tf line 53, in resource "local_file" "kubespray_inventory":
│ 53: k8s_node_host = replace(join("\", \"\n", local.all_nodes), "\", \"", "")
│ ├────────────────
│ │ local.all_nodes is a list of object, known only after apply
│
│ Invalid value for "lists" parameter: incorrect list element type: string required.
这是我的本地人块的样子:
locals {
all_nodes_verbose_etcd = [for k, v in var.node_hosts:
format("%s ip=%s etcd_instance=%s", v.name, v.ipv4_address, v.etcd_instance)
if length(v.etcd_instance) > 0]
all_nodes_verbose = [for k, v in var.node_hosts:
format("%s ip=%s", v.name, v.ipv4_address)
if length(v.etcd_instance) == 0]
master_nodes = [for k, v in var.node_hosts:
v.name
if v.compute_node != true]
etcd_nodes = [for k, v in var.node_hosts:
v.name
if length(v.etcd_instance) > 0]
all_nodes = values(var.node_hosts)[*].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)
}
kubespray_invenotory.tpl 模板:
[all]
${k8s_node_host_verbose_etcd}
${k8s_node_host_verbose}
[kube-master]
${k8s_master_host}
[etcd]
${k8s_etcd_host}
[kube-node]
${k8s_node_host}
[calico-rr]
[k8s-cluster:children]
kube-master
kube-node
calico-rr
这是引发错误的 local_file 资源:
resource "local_file" "kubespray_inventory" {
content = templatefile("${path.module}/templates/var.kubespray_inventory.tpl", {
k8s_node_host_verbose_etcd = replace(join("\", \"\n", local.all_nodes_verbose_etcd), "\", \"", "")
k8s_node_host_verbose = replace(join("\", \"\n", local.all_nodes_verbose), "\", \"", "")
k8s_master_host = replace(join("\", \"\n", local.master_nodes), "\", \"", "")
k8s_etcd_host = replace(join("\", \"\n", local.etcd_nodes), "\", \"", "")
k8s_node_host = replace(join("\", \"\n", local.all_nodes), "\", \"", "")
})
filename = local.kubespray_inv_file
depends_on = [
null_resource.kubespray
]
}
这是我的 variables.tf 文件中 node_hosts 的定义:
variable "node_hosts" {
type = map(map(object({
name = string
compute_node = bool
etcd_instance = string
ipv4_address = string
})))
}
这就是我的 tfvars 文件中 node_hosts 的样子:
node_hosts = {
default = {
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"
}
}
}
我试图通过将嵌套映射最底层的名称元素更改为列表来解决此问题,但这只会导致不同的错误。奇怪的是,当我在变量文件中取消 node_hosts 的定义并使用:
variable node_hosts = {
default = {
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"
}
}
}
该代码有效,我想知道在我的 tfvars 文件中使用 default = 是否不正确。
解决方案
一切似乎都很好,除了你的default
和变量node_hosts
不匹配。在我看来,如果您按如下方式制作它们,它将起作用:
variable "node_hosts" {
type = map(object({
name = string
compute_node = bool
etcd_instance = string
ipv4_address = string
}))
}
在tfvars中它将是:
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"
}
}