无法在 Terraform 中将公共 IP 附加到 Azure Windows VM(使用 for_each 创建)

时间:2021-04-18 13:27:17

标签: azure terraform azure-virtual-machine terraform-provider-azure

我使用 terraform 版本:v0.14.6 我一直在尝试将公共 IP 附加到由 terraform 中的 for_each 条件创建的 Azure Windows VM。我无法弄清楚如何使用 for_each 将在不同模块上再次创建的公共 IP 附加到我的模块以创建 Windows VM。以下是我正在使用的脚本:

    data "azurerm_resource_group" "this" {
  count = local.resourcegroup_state_exists == false ? 1 : 0
  name  = var.resource_group_name
}

data "azurerm_subnet" "this" {
  for_each             = var.windows_vm_nics
  name                 = each.value.subnet_name
  virtual_network_name = each.value.vnet_name
  resource_group_name  = var.resource_group_name
}


resource "azurerm_public_ip" "public_ip" {
  for_each            = var.publicIp_variable
  name                = each.value["name"]
  ip_version          = each.value["ip_version"]
  resource_group_name = var.resource_group_name
  location            = var.resource_group_location
  allocation_method     = each.value["allocation"]
  sku                 = each.value["sku"]
  domain_name_label   = each.value["public_ip_dns"]
  idle_timeout_in_minutes  = each.value["idle_timeout_in_minutes"]
  zones               =  each.value["zone"]
  tags = var.publicIp_tags
}

locals {
  resourcegroup_state_exists = false
  public_ip_exists     ={ for k, v in var.windows_vm_nics : k => v if lookup(v, "use_existing_public_ip ", false) == true }
}

resource "azurerm_network_interface" "windows_nics" {
  for_each                      = var.windows_vm_nics
  name                          = each.value.name
  resource_group_name           = local.resourcegroup_state_exists == true ? var.resource_group_name : data.azurerm_resource_group.this.0.name
  location                      = local.resourcegroup_state_exists == true ? var.resource_group_name : data.azurerm_resource_group.this.0.location
  internal_dns_name_label       = lookup(each.value, "internal_dns_name_label", null) #integration testing needs to be done once DNS is created
  enable_ip_forwarding          = lookup(each.value, "enable_ip_forwarding", null)
  enable_accelerated_networking = lookup(each.value, "enable_accelerated_networking", null)
  dns_servers                   = lookup(each.value, "dns_servers", null) #integration testing needs to be done once DNS is created

  dynamic "ip_configuration" {
    for_each = coalesce(each.value.nic_ip_configurations, [])
    content {
      name                          = coalesce(ip_configuration.value.name, format("%s00%d-ip", each.value.name, index(each.value.nic_ip_configurations, ip_configuration.value) + 1))
      subnet_id                     = lookup(data.azurerm_subnet.this, each.key)["id"]
      private_ip_address_allocation = lookup(ip_configuration.value, "static_ip", null) == null ? "dynamic" : "static"
      private_ip_address            = lookup(ip_configuration.value, "static_ip", null)
      public_ip_address_id          = lookup(each.value, "use_existing_public_ip", false) == true ? lookup(azurerm_public_ip.public_ip[each.value["existing_public_ip_name"]],each.key)["id"] :null #[each.value["existing_public_ip_name"]]
      primary = index(each.value.nic_ip_configurations, ip_configuration.value) == 0 ? true : false
    }
  }

  tags = local.tags
  depends_on = [ azurerm_public_ip.public_ip ]
}

以下是我为此创建的变量文件:

        variable "windows_virtual_machine" {
  type = map(object({
    name                                 = string
    vm_size                              = string
    zone                                 = string
    assign_identity                      = bool
    availability_set_key                 = string
    vm_nic_keys                          = list(string)
    source_image_reference_publisher     = string
    source_image_reference_offer         = string
    source_image_reference_sku           = string
    source_image_reference_version       = string
    os_disk_name                         = string
    storage_os_disk_caching              = string
    storage_account_type                 = string
    disk_size_gb                         = number
    write_accelerator_enabled            = bool
    license_type                         = string
    ultra_ssd_enabled                    = bool
    custom_data_path                     = string
    custom_data_args                     = map(string)
  }))
  description = "Map containing Windows VM objects"
  default     = {}
}

我相信 public_ip_address_id = lookup(each.value, "use_existing_public_ip", false) == true ? lookup(azurerm_public_ip.public_ip[each.value["existing_public_ip_name"]],each.key)["id"] :null #[each.value["existing_public_ip_name"]] 是我需要进行修改的地方,但不太确定出了什么问题。 Terraform 在运行脚本时不会抛出任何错误,但也不会附加公共 IP。

下面是nic的变量文件:

    variable "windows_vm_nics" {
  type = map(object({
    name                          = string
    subnet_name                   = string
    vnet_name                     = string
    networking_resource_group     = string
    internal_dns_name_label       = string
    enable_ip_forwarding          = bool
    enable_accelerated_networking = bool
    use_existing_public_ip               = bool
    existing_public_ip_name              = string
    existing_public_ip_rg_name           = string
    dns_servers                   = list(string)
    nic_ip_configurations = list(object({
      name      = string
      static_ip = string
    }))
  }))
  description = "Map containing Windows VM NIC objects"
  default     = {}
}

我收到以下错误:

 public_ip_address_id          = lookup(each.value, "use_existing_public_ip", false) == true ? lookup(azurerm_public_ip.public_ip[each.value["existing_public_ip_name"]],each.key)["id"] :null #[each.value["existing_public_ip_name"]]
|----------------
| azurerm_public_ip.public_ip is object with 1 attribute "public_IP_1"
| each.value["existing_public_ip_name"] is "Windows-PIP"

给定的键未标识此集合值中的元素。

以下是我使用过的 tfvars :

resource_group_name     = "rg-terraform"
resource_group_location = "East US"
publicIp_variable = {
  "public_IP_1" = {
    name    = "Windows-PIP"
    ip_version       = "IPv4"
    allocation       = "Static"
    sku              = "Standard"
    public_ip_dns    =  null
    idle_timeout_in_minutes     =  null 
    zone             =  null 
}
}


windows_vm_nics = {
     nic1 = {
        name                      = "neudesicdemovm01-nic1"
        subnet_name               = "subnet1"
        vnet_name                 = "terraform_vnet"
        networking_resource_group = null
        use_existing_public_ip               = true
        existing_public_ip_name          ="Windows-PIP"
        existing_public_ip_rg_name           ="rg-terraform"
        internal_dns_name_label       = null
        enable_ip_forwarding          = null 
        enable_accelerated_networking = null 
        dns_servers                   = null
        nic_ip_configurations = [
          {
            static_ip = null
            name      = "ip-config"
          }
        ]   
    } 
    }

1 个答案:

答案 0 :(得分:0)

我发现您在 public_ip_address_id = lookup(each.value, "use_existing_public_ip", false) == true ? lookup(data.azurerm_public_ip.this, each.key)["id"] 中有 resource "azurerm_network_interface" "windows_nics"for_each = var.windows_vm_nics。但是,use_existing_public_ip 中没有 variable "windows_vm_nics" 属性。您可以尝试添加它。

例如:

variable "windows_vm_nics" {
  type = map(object({
    name                      = string
    subnet_name               = string
    vnet_name                 = string
    networking_resource_group = string
    internal_dns_name_label       = string
    enable_ip_forwarding          = bool
    enable_accelerated_networking = bool
    dns_servers                   = list(string)
    use_existing_public_ip               = bool   # add this
    nic_ip_configurations = list(object({
      name      = string
      static_ip = string
    }))
  }))
  description = "Map containing Windows VM NIC objects"
  default     = {}
}