子网未创建

Subnet not creating

我一直收到这个奇怪的错误,有没有解决办法。

 data "azurerm_resource_group" "rg" {
      name     = var.resource_group_name
      #environment = var.environment
      
    }

resource "azurerm_virtual_network" "vnet" {
  name                = var.vnet_name
  location            = var.location
  resource_group_name = var.resource_group_name
  address_space       = var.address_space
}

resource "azurerm_subnet" "subnet" {
  
  name                 = var.subnet_name
  resource_group_name  = var.resource_group_name
  virtual_network_name = var.vnet_name
  
  address_prefixes       = ["10.0.0.0/24"]
  service_endpoints    = ["Microsoft.Sql"]
  delegation {
    name = "delegation"

    service_delegation {
      name    = "Microsoft.ContainerInstance/containerGroups"
      actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action"]
    }
  }
}

我一直收到这个错误

azurerm_subnet.subnet: Creating...
azurerm_virtual_network.vnet: Creating...
azurerm_virtual_network.vnet: Creation complete after 5s [id=/subscriptions/e4da9536-6759-4506-b0cf-10c70facd033/resourceGroups/rg-sagar/providers/Microsoft.Network/virtualNetworks/vnet]
╷
│ Error: creating Subnet: (Name "subnet" / Virtual Network Name "vnet" / Resource Group "rg-sagar"): network.SubnetsClient#CreateOrUpdate: Failure sending request: StatusCode=404 -- Original Error: Code="ResourceNotFound" Message="The Resource 'Microsoft.Network/virtualNetworks/vnet' under resource group 'rg-sagar' was not found. For more details please 
go to https://aka.ms/ARMResourceNotFoundFix"│
│   with azurerm_subnet.subnet,
│   on main.tf line 14, in resource "azurerm_subnet" "subnet":
│   14: resource "azurerm_subnet" "subnet" {
│

即使在创建了 vnet 之后,也无法创建 vnet,不知道我该如何使它工作 知道如何解决这个问题吗?

您需要使用此语句 virtual_network_name = azurerm_virtual_network.vnet.name 而不是 virtual_network_name = var.vnet_name

因为 subnet 资源块中的 virtual_network_name = var.vnet_name 同时创建了 subnetvnet,所以这不适合 azure。因为subnet依赖Vnet。所以 Vnet 应该先创建。所以你需要使用 virtual_network_name = azurerm_virtual_network.vnet.name 来使用现有的 Vnet。

地形代码

provider "azurerm" {
  features{}
}

data "azurerm_resource_group" "rg" {
      name     = var.resource_group_name
      #environment = var.environment
      
    }

resource "azurerm_virtual_network" "vnet" {
  name                = var.vnet_name
  location            = data.azurerm_resource_group.rg.location
  resource_group_name = var.resource_group_name
  address_space       = var.address_space
}

resource "azurerm_subnet" "subnet"{
  name                 = var.subnet_name
  resource_group_name  = var.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet.name
  
  address_prefixes       = ["10.0.0.0/24"]
  service_endpoints    = ["Microsoft.Sql"]
  delegation {
    name = "delegation"

    service_delegation {
      name    = "Microsoft.ContainerInstance/containerGroups"
      actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action"]
    }
  }
}

我认为这个问题需要更多解释,因为代码没有任何问题。 Terraform 试图在创建资源的方式上变得聪明,因此它尝试在一个 运行 中创建尽可能多的资源。这就是为什么有一个名为 -parallelism:

的选项
  -parallelism=n         Limit the number of parallel resource operations.
                         Defaults to 10.

这意味着当 运行 宁 terraform apply 时,Terraform 将尝试 运行 10 个资源操作,包括资源创建。在您的情况下,它将尝试同时创建 vnetsubnet 资源(并行适用于 applyplandestroy)。但是,由于您在两个资源 (var.vnet_name) 中使用相同的变量,Terraform 不知道两者之间存在依赖关系。如果您首先创建 vnet 并添加 subnet 资源 创建 vnet 之后,您现在构建代码的方式将起作用.或者,如果您喜欢冒险,可以将并行度设置为 1。由于您可能不希望这样,因此告诉 Terraform 以何种顺序创建内容的最佳方法是使用资源依赖项。 Terraform 具有 implicit [1] 和 explicit [2] 依赖关系的概念。依赖关系帮助 Terraform 根据它创建的图表决定需要创建什么 [3]。

您的情况有两种选择:

  1. vnetsubnet
  2. 之间创建隐式依赖
  3. vnetsubnet
  4. 之间创建显式依赖关系

由于仅在没有其他方法告诉 Terraform 两个资源相互依赖的情况下才建议使用 depends_on(或显式依赖),因此最好的方法是使用隐式依赖:

data "azurerm_resource_group" "rg" {
 name = var.resource_group_name
}

resource "azurerm_virtual_network" "vnet" {
  name                = var.vnet_name
  location            = var.location
  resource_group_name = var.resource_group_name
  address_space       = var.address_space
}

resource "azurerm_subnet" "subnet" {
  
  name                 = var.subnet_name
  resource_group_name  = var.resource_group_name
  virtual_network_name = azurerm_virtual_network.vnet.name # <-- implicit dependency
  
  address_prefixes       = ["10.0.0.0/24"]
  service_endpoints    = ["Microsoft.Sql"]
  delegation {
    name = "delegation"

    service_delegation {
      name    = "Microsoft.ContainerInstance/containerGroups"
      actions = ["Microsoft.Network/virtualNetworks/subnets/join/action", "Microsoft.Network/virtualNetworks/subnets/prepareNetworkPolicies/action"]
    }
  }
}

vnet 资源在创建后会导出一些属性 [4],包括 name 属性。这有助于创建隐式依赖:通过引用资源和可用属性之一 创建资源后,您告诉 Terraform 它首先需要创建 vnet 并且只有在它可用后才能开始 subnet 创建。


[1] https://www.terraform.io/language/resources/behavior#resource-dependencies

[2] https://www.terraform.io/language/meta-arguments/depends_on

[3]https://www.terraform.io/internals/graph#resource-graph

[4]https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network#attributes-reference