簡體   English   中英

Terraform Apply Error: Code="InvalidResourceName" Message="Resource name is invalid" 創建 VPN-GW 模塊時

[英]Terraform Apply Error: Code="InvalidResourceName" Message="Resource name is invalid" When creating VPN-GW Module

執行 Terraform 應用命令時,我收到以下錯誤。


│ Error: Creating/Updating Virtual Network Gateway: (Name "VPN-GW-HUB-dev" / Resource Group "RG-HUB-dev"): network.VirtualNetworkGatewaysClient#CreateOrUpdate: Failure sending request: StatusCode=400 -- Original Error: Code="InvalidResourceName" Message="Resource name  is invalid. The name can be up to 80 characters long. It must begin with a word character, and it must end with a word character or with '_'. The name may contain word characters or '.', '-', '_'." Details=[]
│ 
│   with module.MOD-VPN-GW.azurerm_virtual_network_gateway.vpngw,
│   on Modules/10.VPN-GW/main.tf line 31, in resource "azurerm_virtual_network_gateway" "vpngw":
│   31: resource "azurerm_virtual_network_gateway" "vpngw" {


我想做什么?

我的 Terraform 代碼在 Azure 中創建了一個完整的 Hub-and-Spoke 基礎設施。在我決定模塊化 VPN GW 部分之前,它運行良好。

我的Terraform代碼結構是通常的格式:

--Modules/{module-name}/main.tf
--main.tf

所以在 {module-name} - 我有一個名為的文件夾:

10.VPN-GW\main.tf

我嘗試了什么?

好吧,我已經嘗試重新格式化代碼,我針對所有其他工作正常的模塊仔細檢查了它。 我不知道為什么會發生這個錯誤,現在已經 3 天不停地調試了。

模塊文件在這里:

#------------------------------
# VPN GW MODULE FILE - ALso contains GW SUBNET
#-------------------------------

resource "azurerm_subnet" "gwSubnet" {
  name                 =    var.subnet_name
  resource_group_name  =    var.subnet_resource_group_name
  virtual_network_name =    var.subnet_virtual_network_name
  address_prefixes     =    var.subnet_address_prefixes

}

variable "subnet_name" {
    type = string
}

variable "subnet_resource_group_name" {
    type = string
}

variable "subnet_virtual_network_name" {
    type = string
}

variable "subnet_address_prefixes" {
    type = list(string)
}


output "outSubnetIDVPNGW" {
    value = azurerm_subnet.gwSubnet.id
}
 

resource "azurerm_virtual_network_gateway" "vpngw" {
  name                = "${var.vpn-gw-name}"
  location            = "${var.vpn-gw-location}"
  resource_group_name = "${var.vpngw_resource_group_name}"

  type     = "Vpn"
  vpn_type = "RouteBased"
  
  active_active = false
  enable_bgp    = false
  sku           = "VpnGw1"

  ip_configuration {
    name                          = "${var.ip_configuration_name}"
    public_ip_address_id          = "${var.ip_configuration_public_ip_address_id}"
    private_ip_address_allocation = "Dynamic"
    subnet_id                     = azurerm_subnet.gwSubnet.id
  }

    vpn_client_configuration {
        address_space = "${var.vpn_client_configuration_address_space}"

        root_certificate {
        name = "${var.root_certificate_name}"
        public_cert_data = "${var.cert}"
    }

    revoked_certificate {
      name       = "${var.revoked_certificate_name}"
      thumbprint = "${var.revoked_certificate_thumbprint}"
    }
  }
}

variable "vpn-gw-name" {
    type = string
    //default = ""
}

variable "vpn-gw-location" {
    //default = ""
    type = string
}

variable "vpngw_resource_group_name" {
    default = ""
}

variable "ip_configuration_name" {
    default = ""
}

variable "ip_configuration_public_ip_address_id" {
    default = ""
}

/*
variable "ip_configuration_private_ip_address_allocation" {
    //default = ""
   // type = string
}
*/

variable "vpn_client_configuration_address_space" {
    default = []
}

variable "root_certificate_name" {
    default = ""
}

variable "cert" {  
    default = ""
}

variable "revoked_certificate_name" {
  default = ""
}

variable "revoked_certificate_thumbprint" {
    default = ""
}

variable "ip_configuration" {
    type = map(string)
}


variable "vpn_client_configuration" {
  type = object({
    address_space           = list(string)
    root_certificate        = map(string)
    revoked_certificate     = map(string)
  })
} 

/*
variable "revoked_certificate" {
  type = map(string)
}
*/

下面給出了調用每個模塊的 main.tf 文件(我只是為導致錯誤的部分添加了片段)——即創建 VPN GW


#-----------------------------------------
# Create GW SUBNET & VPN GW
#-----------------------------------------

module "MOD-VPN-GW" {
  source              = "./Modules/10.VPN-GW"

  subnet_name                 = "GatewaySubnet"
  subnet_resource_group_name  = "RG-HUB-${var.environmentCode}"
  subnet_virtual_network_name =  "VNET-HUB-${var.environmentCode}"
  subnet_address_prefixes     = ["10.0.1.0/27"]

  vpn-gw-name                 = "VPN-GW-HUB-${var.environmentCode}"
  vpn-gw-location               = "westeurope"
  vpngw_resource_group_name   = "RG-HUB-${var.environmentCode}"
  
  ip_configuration = {
    name        = "VNetGatewayConfig"
    public_ip_address_id                    = "${module.MOD-VPNGW-PIP.id}"
    private_ip_address_allocation  = "Dynamic"
    subnet_id                   = module.MOD-VPN-GW.outSubnetIDVPNGW
  }

  vpn_client_configuration = {
    address_space = ["172.16.10.0/24"]

    root_certificate = {
      name = "dev.vpn.macos.com"
      public_cert_data  = data.azurerm_key_vault_certificate.akv-certificate.certificate_data_base64

    }

    revoked_certificate  = {
      name       = "Verizon-Global-Root-CA"
      thumbprint = "912198EEF23DCAC40939312FEE97DD560BAE49B1"
    }
  }

   depends_on = [
     module.MOD-RG-HUB, module.MOD-VNET-HUB, azurerm_linux_virtual_machine.label-vm-spoke-01
  ]

}

我在尋找什么?

我似乎無法在谷歌搜索中找到這個特定的錯誤代碼。 它沒有告訴我給我的 VPN GW 的名稱不正確 - 它給我名稱(在錯誤消息中)並告訴我沒有給出名稱。 這很奇怪。 還是我誤解了錯誤信息?

terraform init 命令成功。 terraform 驗證命令成功。 terraform 計划命令成功。

申請時失敗

root模塊和VPN GW模塊之間存在問題。 Terraform 中模塊的工作方式類似於其他編程語言中的函數:它們需要特定的輸入變量,然后這些變量會被提供給它們的值替換。 更多關於 [1] 中的模塊。

要重構此代碼,我將在root模塊中執行以下操作:

  source = "./Modules/10.VPN-GW"

  subnet_name                 = "GatewaySubnet"
  subnet_resource_group_name  = "RG-HUB-${var.environmentCode}"
  subnet_virtual_network_name = "VNET-HUB-${var.environmentCode}"
  subnet_address_prefixes     = ["10.0.1.0/27"]

  vpn-gw-name               = "VPN-GW-HUB-${var.environmentCode}"
  vpn-gw-location           = "westeurope"
  vpngw_resource_group_name = "RG-HUB-${var.environmentCode}"

  ip_configuration_name                 = "VNetGatewayConfig"
  ip_configuration_public_ip_address_id = module.MOD-VPNGW-PIP.id

  vpn_client_configuration_address_space = ["172.16.10.0/24"]
  root_certificate_name                  = "dev.vpn.macos.com"
  cert                                   = data.azurerm_key_vault_certificate.akv-certificate.certificate_data_base64

  revoked_certificate_name       = "Verizon-Global-Root-CA"
  revoked_certificate_thumbprint = "912198EEF23DCAC40939312FEE97DD560BAE49B1"

}

如您所見,我所做的唯一更改是將值分配給VPN GW模塊所需的變量。 它的工作方式是當模塊被調用時,它會被提供變量的值並且它會知道如何處理它們。 無需在主叫 ( root ) 和被叫模塊 ( VPN GW ) 中定義相同的塊。 因此,將root模塊想象成一段調用 function 的代碼,類似於:

MOD_VPN_GW(subnet_name, subnet_resource_group_name, subnet_virtual_network_name, subnet_address_prefixes, vpn-gw-name, vpn-gw-location, vpngw_resource_group_name, ip_configuration_name, ip_configuration_public_ip_address_id, vpn_client_configuration_address_space, root_certificate_name, cert, revoked_certificate_name, revoked_certificate_thumbprint)

至於您關於如何訪問su.net_id的問題,這是簡單的部分。 VPN GW模塊中,有一個用於azurerm_su.net的資源塊:

resource "azurerm_subnet" "gwSubnet" {
  name                 = var.subnet_name
  resource_group_name  = var.subnet_resource_group_name
  virtual_network_name = var.subnet_virtual_network_name
  address_prefixes     = var.subnet_address_prefixes
}

此資源在創建后提供的屬性之一是 su.net ID [2]。這意味着您可以通過使用此語法 [3] 引用結果值來分配屬性值:

<resource type>.<resource_name>.<attribute>

在你的情況下是:

azurerm_subnet.gwSubnet.id

該值已在azurerm_virtual.network_gateway資源的su.net_id參數中引用:

subnet_id = azurerm_subnet.gwSubnet.id

這意味着它不需要作為模塊的輸入變量之一。 好消息是VPN GW模塊將知道創建資源的順序,因為這是隱式依賴。


[1] https://www.terraform.io/language/modules/develop

[2] https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/su.net#id

[3] https://www.terraform.io/language/expressions/references#references-to-resource-attributes

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM