【问题标题】:Get ip adress and hostname output in terraform在 terraform 中获取 ip 地址和主机名输出
【发布时间】:2021-03-12 14:32:20
【问题描述】:

所以我开始探索 Terraform,到目前为止,我能够在 Azure 中启动我的网络和虚拟机。 由于我创建了 7 个 VM,因此我想获取它的 IP 地址和主机名。

在我的 main.tf 我有这个:

provider "azurerm" {
  features {}
  # Configuration options
}



module "splunk_architect" {  
  source = "./modules/architect"
  
}

只是我在 /modules/architect 中的 main.tf 中的一个示例

resource "azurerm_network_interface" "main" {
    for_each = toset(var.vm_names)
  name                = "${each.value}-nic"
  location            = azurerm_resource_group.rsg.location
  resource_group_name = azurerm_resource_group.rsg.name


  ip_configuration {
    name                          = "testconfiguration1"
    subnet_id                     = azurerm_subnet.subnet.id
    private_ip_address_allocation = "Dynamic"
    public_ip_address_id          = azurerm_public_ip.pubip[each.key].id
  }

还有我在 /modules/architect 中的 outputs.tf

output "ip" {
  value = azurerm_network_interface.main[each.key].private_ip_address
}

所以当我运行它时,我收到以下错误消息:

Error: Reference to "each" in context without for_each

  on modules\architect\outputs.tf line 6, in output "ip":    6:   value = azurerm_network_interface.main[each.key].private_ip_address

The "each" object can be used only in "module" or "resource" blocks, and only when the "for_each" argument is set.

所以我尝试在模块中设置 for_each,但没有让它工作。 我也通过了文件没有任何成功。 关于我可以尝试打印出每个 VM 的 IP 的任何提示?

【问题讨论】:

    标签: terraform azure-rm


    【解决方案1】:

    由于您有多个虚拟机(使用for_each 声明),您还将有多个私有 IP 地址要返回。您需要为您的模块确定将这些 IP 地址返回给调用者的最佳方式。

    一个常见的答案是返回一个映射,其键是来自var.vm_names 的元素,因此调用者可以轻松地将它传入的 VM 名称与您返回的 IP 地址相关联,如下所示:

    output "ip" {
      value = tomap({
        for name, vm in azurerm_network_interface.main : name => vm.private_ip_address
      })
    }
    

    这是一个for expression,它通过评估每个元素的表达式,从现有数据结构构造一个新的数据结构。在这种情况下,它从azurerm_network_interface.main 中获取键——这将匹配for_each 中给出的值——并将它们映射到每个对象的private_ip_address 属性。

    因此,结果将显示为从 VM 名称到 IP 地址的映射,可能如下所示:

    {
      "example1" = "10.1.2.1"
      "example2" = "10.1.2.45"
    }
    

    与您的问题没有直接关系,但还要注意,如果您的模块只使用 var.vm_names 作为一个集合,那么最好首先将其声明为一个集合,而不是在每次使用时转换它,因为那样你的模块的用户会更清楚,里面的字符串顺序无关紧要,并且不能有两个元素具有相同的字符串:

    variable "vm_names" {
      type = set(string)
    }
    

    使用该声明,var.vm_names 将已经是一组字符串,因此您无需在 for_each 中显式转换它:

      for_each = var.vm_names
    

    【讨论】:

      猜你喜欢
      • 2012-05-31
      • 2014-04-12
      • 1970-01-01
      • 1970-01-01
      • 2018-01-02
      • 2018-08-26
      • 2012-04-12
      • 1970-01-01
      相关资源
      最近更新 更多