【问题标题】:Terraform : Using for_each in moduleTerraform:在模块中使用 for_each
【发布时间】:2021-04-14 14:26:09
【问题描述】:

我使用的是 terraform 版本 0.14.3。 我有一个用于创建 Azure 网络接口卡的模块,如下所示:

resource "azurerm_network_interface" "nic" {

  name                = var.nic_name
  location            = var.location
  resource_group_name = var.rg_name

  ip_configuration {
    name                          = var.ipconfig_name
    subnet_id                     = var.subnet_id
    private_ip_address_allocation = "Dynamic"
  }
}

它的输出定义为:

output "nic_id" {
     value = azurerm_network_interface.nic.id 
}

我在这个父模块中调用这个模块:

module "NIC" {
  source = "./NIC"
  for_each = var.nics

  nic_name      = each.value.nic_name
  location      = "eastus2"
  rg_name       = "abc-test-rg"
  ipconfig_name = each.value.ipconfig_name
  subnet_id     = <subnet_id>
}

output "nic_ids" {
  value = [for k in module.NIC.nic_id : k.id]
} 

网卡值定义如下:

nics = {
  nic1 = {
    nic_name      = "abc-nic-1"
    ipconfig_name = "nic-1-ipconfig"
  }
}

我想循环显示 NIC 输出 ID,并希望它们显示出来。 当我运行上面的代码时,我在 terraform plan 中遇到以下错误:

Error: Unsupported attribute

  on main.tf line 15, in output "nic_ids":
  15:   value = [for k in module.NIC.nic_id : k.id]
    |----------------
    | module.NIC is object with 1 attribute "nic1"

This object does not have an attribute named "nic_id".

我该如何解决?

【问题讨论】:

    标签: azure terraform terraform-provider-azure


    【解决方案1】:

    您的module "NIC" 块已设置for_each,因此模块中其他位置的module.NIC 符号是从实例键到输出对象的映射,而不是像单例模块那样只是单个输出对象。

    Terraform 的错误消息试图通过以下消息引起注意:

    • module.NIC is object with 1 attribute "nic1"

    请注意,这里的 nic1 是来自您的 var.nics 的键,不是在您的模块中定义的输出值之一。

    假设您在此处显示的 nic_id 输出是该模块中唯一定义的输出,则 module.NIC 值的形状如下:

    {
      nic1 = {
        nic_id = "eni-e5aa89a3"
      }
    }
    

    听起来你想产生一个像这样形状的值:

    {
      nic1 = "eni-e5aa89a3"
    }
    

    如果是这样,获得该结果的合适表达式如下:

    output "nic_ids" {
      value = { for k, nic in module.NIC : k => nic.nic_id }
    } 
    

    上述意思是:为NIC模块的每个实例生成一个映射,其键为模块实例键,其值为nic_id输出值。

    或者,如果哪个 id 属于哪个实例并不重要,那么您可以生成一组无序的 id,如下所示:

    output "nic_ids" {
      value = toset([for nic in module.NIC : nic.nic_id])
    } 
    

    在这种情况下,for 表达式只定义了一个本地符号nic,它表示模块实例对象,因为它对实例键没有任何作用。这里的 toset 表示 ID 没有任何特定的顺序:这不是绝对必要的,但我认为确保任何其他依赖于该值的 Terraform 代码不会无意中是一个好习惯 取决于当前 id 的任意顺序,如果您在 var.nics 中添加或删除元素,将来可能会发生变化。

    【讨论】:

    • 谢谢马丁,让我试试看。
    猜你喜欢
    • 2021-03-07
    • 2021-03-31
    • 2021-05-09
    • 1970-01-01
    • 2021-03-21
    • 2021-01-03
    • 2021-09-24
    • 2021-07-09
    • 2021-08-16
    相关资源
    最近更新 更多