Terraform变量定义语法错误及属性访问问题求助
搞定这个Terraform变量问题很简单,我来帮你捋清楚!
问题根源分析
你之前的错误是因为map类型变量的default值格式不正确。Terraform的map需要键值对(key = value)的结构,但你直接在{}里嵌套了对象{...}却没有指定对应的键,所以Terraform报错说“Expected an attribute value”——它在等号的位置找不到键值对的定义。
另外你尝试改用list类型的问题在于:list是有序集合,只能通过索引(比如var.apps[0])访问元素,没法像你想要的那样通过名称(var.apps.app1_name)直接定位到对应属性,所以不符合需求。
正确的变量配置方案
要实现var.apps.xxx的访问方式,我们需要正确定义map(object)类型的变量,给每个对象分配一个唯一的键。下面提供两种符合需求的方案:
方案一:保留独立的app_name属性(推荐)
这种方案更清晰,允许你在对象中明确存储应用名称,键可以用更简洁的标识(比如app1):
# apps变量的正确配置 variable "apps" { type = map(object({ app_name = string labels = map(string) annotations = map(string) })) default = { app1 = { app_name = "app1_name" labels = { "name" = "stream-frontend" "tier" = "web" "owner" = "product" } annotations = { "serviceClass" = "web-frontend" "loadBalancer/class" = "external" } }, app2 = { app_name = "app2_name" labels = { "name" = "stream-backend" "tier" = "api" "owner" = "engineering" } annotations = {} } } } # acl变量的正确配置 variable "acl" { type = map(object({ acl_name = string ingress = string egress = string port = string protocol = string })) default = { frontend = { acl_name = "acl_frontend" ingress = "0.0.0.0/0" egress = "10.0.0.0/24" port = "80" protocol = "tcp" }, backend = { acl_name = "acl_backend" ingress = "10.0.0.0/24" egress = "0.0.0.0/0" port = "8080" protocol = "tcp" } } }
访问方式示例:
- 获取app1的名称:
var.apps.app1.app_name - 获取app1的labels:
var.apps.app1.labels - 获取前端ACL的端口:
var.acl.frontend.port
方案二:将应用名称作为map的键(简洁版)
如果你不需要在对象中重复存储应用名称,可以直接把app_name作为map的键,这样能更直接地通过名称访问:
variable "apps" { type = map(object({ labels = map(string) annotations = map(string) })) default = { app1_name = { labels = { "name" = "stream-frontend" "tier" = "web" "owner" = "product" } annotations = { "serviceClass" = "web-frontend" "loadBalancer/class" = "external" } } } }
访问方式示例:
- 获取app1_name的labels:
var.apps.app1_name.labels - 如果需要应用名称字符串,直接使用键即可(比如
"app1_name"),或者通过keys(var.apps)遍历所有应用名称
总结
两种方案都能满足你通过名称访问属性的需求,方案一更适合需要明确存储应用名称的场景,方案二则更简洁。根据你的实际业务需求选择即可。
内容的提问来源于stack exchange,提问作者zolo
相关产品推荐
相关产品推荐

