`在同一虚拟网络中创建多个子网时,我们看到以下错误。有人可以指导我如何实现这一目标吗?想知道我们是否可以使用 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]
}
使用 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]
}
部署成功: