繁体   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