我们无法使用 cvs 作为输入文件在同一 vnet 下使用 terraform 创建多个子网

问题描述 投票:0回答:1

`在同一虚拟网络中创建多个子网时,我们看到以下错误。有人可以指导我如何实现这一目标吗?想知道我们是否可以使用 csv 输入作为变量,请在此处发布您的建议。谢谢你

azureuser@aztfserver:\~/az_csv_tasks_new$ sudo terraform apply  -auto-approve
╷
│ Error: Duplicate object key
│
│   on rg_vnets_subnets.tf line 24, in resource "azurerm_resource_group" "rg":
│   24:   for_each = { for v in local.vnet_config : v.resource_group_name =\> v }
│     ├────────────────
│     │ v.resource_group_name is "rg-ScriptTest-wus-002"
│
│ Two different items produced the key "rg-ScriptTest-wus-002" in this 'for' expression. If         duplicates are expected, use the  
│ ellipsis (...) after the value expression to enable grouping by key.

更新省略号 (...) 后,我们看到此错误

azureuser@aztfserver:~/az_csv_tasks_new$ sudo terraform apply -自动批准

│ 错误:对象键重复 │ │ rg_vnets_subnets.tf 第 24 行,在资源“azurerm_resource_group”“rg”中: │ 24: for_each = { for v in local.vnet_config : v.resource_group_name => v } │ ├──────────────── │ │ v.resource_group_name 为“rg-ScriptTest-wus-002” │ │ 两个不同的项目在此“for”表达式中生成了密钥“rg-ScriptTest-wus-002”。如果需要重复,请使用
│ 值表达式后面的省略号 (...) 以启用按键分组。 ╵ azureuser@aztfserver:~/az_csv_tasks_new$

以下是配置文件。

cat rg_vnets_subnets.csv

resource_group_name,location,vnet_name,vnet_address_space,subnet_name,subnet_address_space
rg-ScriptTest-eus-001,East US,vnet-ScriptTest-eus-001,10.0.0.0/16,subnet1,10.0.1.0/26
rg-ScriptTest-wus-002,West US,vnet-ScriptTest-wus-002,11.0.0.0/16,subnet2,11.0.1.0/26
rg-ScriptTest-wus-002,West US,vnet-ScriptTest-wus-002,11.0.0.0/16,subnet3,11.0.2.0/26

#cat main.tf

locals {
  vnet_config = csvdecode(file("${path.module}/rg_vnets_subnets.csv"))
}

resource "azurerm_resource_group" "rg" {
  for_each = { for v in local.vnet_config : v.resource_group_name => v }
  name     = each.value.resource_group_name
  location = each.value.location
}

resource "azurerm_virtual_network" "vnet" {
  for_each            = { for v in local.vnet_config : v.vnet_name => v }
  name                = each.value.vnet_name
  location            = each.value.location
  resource_group_name = each.value.resource_group_name
  address_space       = [each.value.vnet_address_space]
  depends_on          = [azurerm_resource_group.rg]
}

resource "azurerm_subnet" "subnet" {
  for_each            = { for v in local.vnet_config : "${v.vnet_name}-${v.subnet_name}" => v }
  name                = each.value.subnet_name
  resource_group_name = each.value.resource_group_name
  virtual_network_name = each.value.vnet_name
 address_prefixes     = [each.value.subnet_address_space]
 depends_on          = [azurerm_virtual_network.vnet]
}

在此输入图片描述

terraform terraform-provider-azure azure-rm-template
1个回答
0
投票

使用 cvs 作为输入文件,在同一 vnet 下使用 terraform 创建多个子网。

我尝试了您分享的配置,但最终遇到了与您提到的相同的困难。我们遇到的错误是因为“重复对象键”的出现是因为您的 Terraform 配置在使用

for_each
结构时尝试使用相同的键创建资源组条目。问题是您的 CSV 文件包含多个具有相同
resource_group_name
的条目,这些条目用作
for_each
映射中的键。当 Terraform 处理此问题时,它会遇到重复的键并引发错误。

我根据您的要求使用 CSV 文件输入尝试了新的更新的 terraform 配置,并且能够成功配置。

测试.csv

resource_group_name,location,vnet_name,vnet_address_space,subnet_name,subnet_address_space
rgvk-ScriptTest-eus-001,East US,vnet-ScriptTest-eus-001,10.0.0.0/16,subnet1,10.0.1.0/26
rgvk-ScriptTest-wus-002,West US,vnet-ScriptTest-wus-002,11.0.0.0/16,subnet2,11.0.1.0/26
rgvk-ScriptTest-wus-002,West US,vnet-ScriptTest-wus-002,11.0.0.0/16,subnet3,11.0.2.0/26

我的地形配置:

provider "azurerm" {
  features {}
}

locals {
  vnet_config = csvdecode(file("${path.module}/test.csv"))
  // Creating a unique set of resource groups based on 'resource_group_name' and 'location'.
   unique_resource_groups = { for idx, v in local.vnet_config : "${v.resource_group_name}-${v.location}-${idx}" => v }
}

resource "azurerm_resource_group" "rg" {
  for_each = local.unique_resource_groups
  name     = each.value.resource_group_name
  location = each.value.location
}

resource "azurerm_virtual_network" "vnet" {
  for_each = { for idx, v in local.vnet_config : "${v.resource_group_name}-${v.vnet_name}-${idx}" => v }
  name                = each.value.vnet_name
  location            = each.value.location
  resource_group_name = each.value.resource_group_name
  address_space       = [each.value.vnet_address_space]
  depends_on          = [azurerm_resource_group.rg]
}


resource "azurerm_subnet" "subnet" {
  for_each            = { for v in local.vnet_config : "${v.vnet_name}-${v.subnet_name}" => v }
  name                = each.value.subnet_name
  resource_group_name = each.value.resource_group_name
  virtual_network_name = each.value.vnet_name
  address_prefixes    = [each.value.subnet_address_space]
  depends_on          = [azurerm_virtual_network.vnet]
}

部署成功:

enter image description here

enter image description here

enter image description here

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.