Terraform - 使用 for_each 时获取特定虚拟机的公共 IP

时间:2021-05-05 14:42:48

标签: terraform terraform-provider-azure

我有一个名为变量“publicvms”的变量,它由使用 for_each 循环创建的 3 个 linux VM 组成,如下所示: vm.hostnames 是 VM1、VM2、VM3

resource "azurerm_virtual_machine" "publicvm" {
  for_each = { for vm in var.publicvms : vm.hostname => vm }

  provider                         = azurerm.xxxxxxxxxxxxxxxxxxxx
  name                             = each.value.hostname
  location                         = var.vm_location
  resource_group_name              = var.vm_resource_group
  network_interface_ids            = [azurerm_network_interface.publicnic[each.key].id]
  vm_size                          = each.value.size
  delete_data_disks_on_termination = true
  delete_os_disk_on_termination    = true
  #count                 = var.prometheus_group["instance_count"]

  storage_os_disk {
    name              = "${each.value.hostname}-Disk"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    disk_size_gb      = each.value.disk_size_gb
    managed_disk_type = each.value.managed_disk_type

  }
  storage_image_reference {
    id = data.azurerm_shared_image_version.search.id
  }

  os_profile {
    computer_name  = each.value.hostname
    admin_username = var.admin_username
    admin_password = var.admin_password
  }

  os_profile_linux_config {
    disable_password_authentication = var.disable_authentication
  }

  tags = merge(var.generic_tags, each.value.extra_tag)
}

上面的 vm 使用 azurerm_public_ip 中的 id 将 ip_address 分配给 vm:

  for_each = { for vm in var.publicvms : vm.hostname => vm }

  provider            = azurerm.microsoftazureenterprise
  name                = "${each.value.hostname}-PublicIP"
  location            = var.vm_location
  resource_group_name = var.vm_resource_group
  allocation_method   = "Static"

  tags = var.generic_tags
}

我想创建一个变量来存储一个特定 VM 的值,因为我将使用该变量创建一个 cloudflare dns 条目。

  zone_id = var.cloudflare_zone_id
  name    = var.web_url_prefix
  value   = $azurerm_public_ip.publicip.Index_key["VM2"].ip_address
  type    = "A"
  proxied = false
}

我已经尝试了上面的值,但它给了我错误:

azurerm_public_ip.publicip 是具有 3 个属性的对象 给定的键未标识此集合值中的元素。

在 tfstate 文件中,我看到以下输出:

      "module": "module.webserver_cluster",
      "mode": "managed",
      "type": "azurerm_public_ip",
      "name": "publicip",
      "provider": "module.webserver_cluster.provider[\"registry.terraform.io/hashicorp/azurerm\"].microsoftazure",
      "instances": [
        {
          "index_key": "VM1",
          "schema_version": 0,
          "attributes": {
            "allocation_method": "Static",
            "domain_name_label": null,
            "fqdn": null,
            "id": REDACTED,
            "idle_timeout_in_minutes": 4,
            "ip_address": "10.10.10.10",
            "ip_version": "IPv4",
            "location": "westeurope",
            "name": "VM1-PublicIP",
            "public_ip_prefix_id": null,
            "resource_group_name": "ResourceGroup1",
            "reverse_fqdn": null,
            "sku": "Basic",
            "tags": {
              "environment": "poc",
              "family": "Infrastructure",
            },
            "timeouts": null,
            "zones": []
          },
          "sensitive_attributes": [],
          "private": "REDACTED"
        },
        {
          "index_key": "VM2",
          "schema_version": 0,
          "attributes": {
            "allocation_method": "Static",
            "domain_name_label": null,
            "fqdn": null,
            "id": "REDACTED",
            "idle_timeout_in_minutes": 4,
            "ip_address": "20.20.20.20",
            "ip_version": "IPv4",
            "location": "westeurope",
            "name": "VM2-PublicIP",
            "public_ip_prefix_id": null,
            "resource_group_name": "ResourceGroup1",
            "reverse_fqdn": null,
            "sku": "Basic",
            "tags": {
              "environment": "poc",
              "family": "Infrastructure",
              "product": "Monitoring"
            },
            "timeouts": null,
            "zones": []
          },
          "sensitive_attributes": [],
          "private": "REDACTED"
        },
        {
          "index_key": "VM3",
          "schema_version": 0,
          "attributes": {
            "allocation_method": "Static",
            "domain_name_label": null,
            "fqdn": null,
            "id": "REDACTED",
            "idle_timeout_in_minutes": 4,
            "ip_address": "30.30.30.30",
            "ip_version": "IPv4",
            "location": "westeurope",
            "name": "VM3-PublicIP",
            "public_ip_prefix_id": null,
            "resource_group_name": "ResourceGroup1",
            "reverse_fqdn": null,
            "sku": "Basic",
            "tags": {
              "environment": "poc",
              "family": "Infrastructure",
              "product": "Monitoring"
            },
            "timeouts": null,
            "zones": []
          },
          "sensitive_attributes": [],
          "private": "REDACTED"
        }
      ]
    }

有没有办法获取ip地址“20.20.20.20”并将其传递给cloudflare_record资源中的“value”??

我试过了:

value   = $azurerm_public_ip.publicip.Index_key["VM2"].ip_address
value   = $azurerm_public_ip.publicip["VM2"].ip_address
value   = $azurerm_public_ip.publicip[1].ip_address
value   = $azurerm_public_ip.publicip["1"].ip_address

无济于事。

问候, 拉杰

1 个答案:

答案 0 :(得分:1)

根据您的要求,您似乎想要获取使用 for_each 循环创建的公共 IP 的 IP 地址。那么应该是这样的:

value = azurerm_public_ip.publicip["VM2"].ip_address

它在状态文件和输出中的显示不同。所以你可以使用输出来显示它的样子:

output "publicIPs" {
  value = azurerm_public_ip.publicip
}

它看起来像这样:

publicIPs = {
  "VM1" = {
    xxxxx
  }
  "VM2" = {
    xxxxx
  }
  "VM3" = {
    xxx
  }
}

是的,如果您使用 for_each 循环,输出将是地图。所以你需要用密钥引用它。

相关问题