模块 + for_each 的输出

问题描述 投票:0回答:2

我有一个使用模块的 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
对象有一个名称,因此在我看来,错误与错误的语法有关。

terraform terraform0.12+
2个回答
164
投票

[*]
.*
运算符仅适用于列表。因为该资源使用
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 表达式仅适用于列表。


65
投票

将其留在这里以防有人感兴趣

output "bd_name" {
  value = values(mso_schema_template_bd.bd).*.name
}
© www.soinside.com 2019 - 2024. All rights reserved.