我有一个使用模块的 Terraform 脚本。我想创建多个资源,所以我使用 for_each 方法。
以下是我的变量配置:
variable bridge_domains {
description = "Bridge Domain"
type = map
default = {
bd1 = {
name = "BD1",
},
bd2 = {
name = "BD2"
}
}
}
在根
main.tf
文件中,我使用 for_each
: 循环该变量
module "schema_template_bd" {
source = "./modules/schema_template_bd"
for_each = var.bridge_domains
schema = module.tenant.mso_schema.id
template = var.template
bd = each.value.name
}
然后在
modules/schema_template_bd
文件中我有以下内容:
resource "mso_schema_template_bd" "bd" {
schema_id = var.schema
template_name = var.template
name = var.bd
}
该模块有一个输出,我在其中定义了以下内容:
output "mso_bd" {
value = mso_schema_template_bd.bd[*]
}
这个想法是输出所有创建的对象的名称。所以我定义了一个
output.tf
文件(在根级别),包含以下代码:
output "bd_name" {
value = module.schema_template_bd.mso_bd.*.name
}
我总是得到:
该对象没有名为“name”的属性。
通常,
bd
对象有一个名称,因此在我看来,错误与错误的语法有关。
[*]
和 .*
运算符仅适用于列表。因为该资源使用 for_each
而不是 count
,所以它在其他表达式中的值是 map,而不是列表。
为了使您的配置正常工作,您需要决定是返回一个名称映射(其中键是
var.bridge_domains
键)还是返回一组 id(调用者无法确定哪个名称属于哪个名称)会更好var.bridge_domains
: 的哪个元素
output "bd_name" {
value = {
for k, bd in mso_schema_template_bd.bd : k => bd.name
}
}
或
output "bd_name" {
value = [
for bd in mso_schema_template_bd.bd : bd.name
]
}
如果在第二个示例中只需要唯一的结果,则可以使用函数
toset
:
output "bd_name" {
value = toset([
for bd in mso_schema_template_bd.bd : bd.name
])
}
for
表达式,它是 splat 表达式 更通用的对应物,可用于任何类型的集合,并且可以生成序列和映射作为其结果,而 splat 表达式仅适用于列表。
将其留在这里以防有人感兴趣
output "bd_name" {
value = values(mso_schema_template_bd.bd).*.name
}