我可以使用 Terraform 对资源执行连续更改吗?

Can I perform consecutive changes on resource with Terraform?

有时我需要使用 TF 对资源执行一些更改(在同一个声明文件中),例如:

  1. 创建 Azure VNET/Subnet A
  2. 创建专用端点
  3. 从 #1 更改子网 A 的属性

我试图用 depends_on 语句创建相同的资源,但它不起作用。

module.vnet-stage2[1].azurerm_virtual_network.vnet: Creating...
module.vnet-stage2[0].azurerm_virtual_network.vnet: Creating...
╷
│ Error: A resource with the ID "/subscriptions/6fd2b24c-1ffa-43ca-abc1-8127c30dcb39/resourceGroups/PE-TF-RG/providers/Microsoft.Network/virtualNetworks/client-vnet" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_virtual_network" for more information.
│
│   with module.vnet-stage2[0].azurerm_virtual_network.vnet,
│   on ../../modules/vnet/main.tf line 6, in resource "azurerm_virtual_network" "vnet":
│    6: resource azurerm_virtual_network "vnet" {
│
╵
╷
│ Error: A resource with the ID "/subscriptions/6fd2b24c-1ffa-43ca-abc1-8127c30dcb39/resourceGroups/PE-TF-RG/providers/Microsoft.Network/virtualNetworks/server-vnet" already exists - to be managed via Terraform this resource needs to be imported into the State. Please see the resource documentation for "azurerm_virtual_network" for more information.
│
│   with module.vnet-stage2[1].azurerm_virtual_network.vnet,
│   on ../../modules/vnet/main.tf line 6, in resource "azurerm_virtual_network" "vnet":
│    6: resource azurerm_virtual_network "vnet" {
│
╵

我尝试使用以下代码测试您的要求。无法从同一声明文件将子网 enforce_private_link_service_network_policies = true 更改为 false

provider "azurerm" {
    features{}
}

data "azurerm_resource_group" "example" {
  name     = "yourresourcegroup"
}

resource "azurerm_virtual_network" "example" {
  name                = "example-network"
  address_space       = ["10.0.0.0/16"]
  location            = data.azurerm_resource_group.example.location
  resource_group_name = data.azurerm_resource_group.example.name
}

resource "azurerm_subnet" "service" {
  name                 = "service"
  resource_group_name  = data.azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.1.0/24"]

  enforce_private_link_service_network_policies = true
}

resource "azurerm_subnet" "endpoint" {
  name                 = "endpoint"
  resource_group_name  = data.azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.2.0/24"]

  enforce_private_link_endpoint_network_policies = true
}

resource "azurerm_public_ip" "example" {
  name                = "example-pip"
  sku                 = "Standard"
  location            = data.azurerm_resource_group.example.location
  resource_group_name = data.azurerm_resource_group.example.name
  allocation_method   = "Static"
}


resource "azurerm_lb" "example" {
  name                = "example-lb"
  sku                 = "Standard"
  location            = data.azurerm_resource_group.example.location
  resource_group_name = data.azurerm_resource_group.example.name

  frontend_ip_configuration {
    name                 = azurerm_public_ip.example.name
    public_ip_address_id = azurerm_public_ip.example.id
  }
}

resource "azurerm_private_link_service" "example" {
  name                = "example-privatelink"
  location            = data.azurerm_resource_group.example.location
  resource_group_name = data.azurerm_resource_group.example.name

  nat_ip_configuration {
    name      = azurerm_public_ip.example.name
    primary   = true
    subnet_id = azurerm_subnet.service.id
  }

  load_balancer_frontend_ip_configuration_ids = [
    azurerm_lb.example.frontend_ip_configuration.0.id,
  ]
}

resource "azurerm_private_endpoint" "example" {
  name                = "example-endpoint"
  location            = data.azurerm_resource_group.example.location
  resource_group_name = data.azurerm_resource_group.example.name
  subnet_id           = azurerm_subnet.endpoint.id

  private_service_connection {
    name                           = "example-privateserviceconnection"
    private_connection_resource_id = azurerm_private_link_service.example.id
    is_manual_connection           = false
  }
}

输出:

当您尝试将值更改为 false 时,您会收到以下错误:

解法:

您可以先在文件上创建 Vnet+Subnet,然后使用 vnet 和子网的数据源在另一个文件中创建专用端点。创建专用端点后,您可以转到 vnet+subnet 文件来更改子网的属性。

您可以一次创建所有内容,然后使用 PowerShell 或 CLI 更改 属性 子网。

CLI 命令:

az network vnet subnet update --disable-private-endpoint-network-policies false --name service --resource-group resourcegroup --vnet-name example-network.

参考:

Manage network policies for private endpoints - Azure Private Link | Microsoft Docs

注意:子网上的 enforce_private_link_service_network_policies = true 是创建专用端点所必需的。创建后可以改成enforce_private_link_service_network_policies = false.