Terraform:模块 + for_each 的输出

wiw*_*978 20 terraform terraform0.12+

我有一个使用模块的 Terraform 脚本。我想创建多个资源,所以我使用了 for_each 方法。

下面是我的变量配置:

variable bridge_domains {
  description = "Bridge Domain"
  type     = map
  default  = {
    bd1 = {
      name  = "BD1",
    },
    bd2 = {
      name    = "BD2"
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

在根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
}
Run Code Online (Sandbox Code Playgroud)

然后在modules/schema_template_bd文件中我有以下内容:

resource "mso_schema_template_bd" "bd" {
  schema_id              =      var.schema
  template_name          =      var.template
  name                   =      var.bd
}
Run Code Online (Sandbox Code Playgroud)

该模块有一个输出,我在其中定义了以下内容:

output "mso_bd" {
  value = mso_schema_template_bd.bd[*]
}
Run Code Online (Sandbox Code Playgroud)

这个想法是输出所有创建的对象的名称。所以我定义了一个output.tf包含以下代码的文件(在根级别):

output "bd_name" {
  value = module.schema_template_bd.mso_bd.*.name
}
Run Code Online (Sandbox Code Playgroud)

我总是得到:

该对象没有名为“name”的属性。

通常该bd对象有一个名称,因此在我看来该错误与错误的语法有关。

小智 58

留在这里以防有人感兴趣

output "bd_name" {
  value = values(mso_schema_template_bd.bd).*.name
}
Run Code Online (Sandbox Code Playgroud)

  • 相同,但使用另一种语法:`values(mso_schema_template_bd.bd)[*].name` (14认同)

Mar*_*ins 42

在[*]和.*运营商都打算只列出使用。因为此资源使用for_each而不是count,所以它在其他表达式中的值是一个映射,而不是一个列表。

为了使您的配置工作,您需要决定是返回一个名称映射,其中键是var.bridge_domains键,还是只返回一组 id,调用者无法确定哪个名称属于哪个名称。的元素var.bridge_domains:

output "bd_name" {
  value = tomap({
    for k, bd in mso_schema_template_bd.bd : k => bd.name
  })
}
Run Code Online (Sandbox Code Playgroud)

或者

output "bd_name" {
  value = toset([
    for bd in mso_schema_template_bd.bd : bd.name
  ])
}
Run Code Online (Sandbox Code Playgroud)

这使用了for表达式,它是splat 表达式的更通用对应物,可以处理任何类型的集合,并且可以生成序列和映射作为结果,而 splat 表达式仅适用于列表。

  • 我想我在回读以修改示例时无意中将您的两个示例组合在一起。您可能需要在两层上执行类似的操作,或者您可以让内部模块直接返回“mso_schema_template_bd.bd”(没有“[*]”或任何其他运算符)以将资源对象的整个映射公开给外部模块。 (2认同)