Terraform:迭代和跳过特定的索引值
Terraform: Iterating and skipping over specific index values
我正在尝试更新我现有的 azurerm_subnet
terraform 代码
被许多其他人消耗掉了。所以我们真的不想破坏任何现有的 tfvars
使用 network_security_group_id
的折旧字段从 azurerm_subnet
到名为 azurerm_network_interface_security_group_association
的新资源,从版本 2.0.
开始
现有代码
resource "azurerm_subnet" "generic_subnet" {
count = "${length(var.subnet_names)}"
name = "${element("${var.subnet_names}", count.index)}"
resource_group_name = "${var.resource_group_name}"
virtual_network_name = "${azurerm_virtual_network.generic_vnet.name}"
address_prefix = "${element("${var.subnet_address_ranges}", count.index)}"
service_endpoints = "${var.service_endpoints[count.index]}"
network_security_group_id = "${element(var.subnet_nsg_ids, count.index)}"
route_table_id = "${element(var.subnet_route_tables, count.index)}"
}
tfvars:
subnet_address_ranges = [
"10.102.40.0/22",
"10.102.44.0/24",
"10.102.45.0/25"
]
subnet_names = [
"private-subnet-01",
"public-subnet-01",
"protected-subnet-01"
]
service_endpoints = [
["Microsoft.AzureCosmosDB","Microsoft.KeyVault", "Microsoft.Storage","Microsoft.Sql","Microsoft.AzureActiveDirectory","Microsoft.ContainerRegistry","Microsoft.EventHub","Microsoft.ServiceBus","Microsoft.Web"],
[],
["Microsoft.KeyVault", "Microsoft.Storage"]
]
subnet_nsg_ids = [
"/subscriptions/yyyy/resourceGroups/yyy/providers/Microsoft.Network/networkSecurityGroups/nsg-01",
"",
"/subscriptions/yyyy/resourceGroups/yyy/providers/Microsoft.Network/networkSecurityGroups/nsg-02"
]
更新代码(通过引入 azurerm_network_interface_security_group_association
资源)
resource "azurerm_subnet" "generic_subnet" {
count = "${length(var.subnet_names)}"
name = "${element("${var.subnet_names}", count.index)}"
resource_group_name = "${var.resource_group_name}"
virtual_network_name = "${azurerm_virtual_network.generic_vnet.name}"
address_prefix = "${element("${var.subnet_address_ranges}", count.index)}"
service_endpoints = "${var.service_endpoints[count.index]}"
network_security_group_id = "${element(var.subnet_nsg_ids, count.index)}"
route_table_id = "${element(var.subnet_route_tables, count.index)}"
}
resource "azurerm_subnet_network_security_group_association" "generic_nsg_association" {
count= "${length(var.subnet_nsg_ids)}"
subnet_id = "${element(azurerm_subnet.generic_subnet.*.id, count.index)}"
network_security_group_id = "${element(var.subnet_nsg_ids, count.index)}"
}
显然我的新资源会通过抛出像
这样的错误来破坏所有 tfvars
Error: Can not parse "network_security_group_id" as a resource id:
Cannot parse Azure ID: parse "": empty url
on ../../../main.tf line 41, in resource
"azurerm_subnet_network_security_group_association"
"generic_nsg_association": 41: network_security_group_id =
"${element(var.subnet_nsg_ids, count.index)}"
原因是我们需要给出 network_security_group_id
参数。但是,我所有现有的 tfvar 都有一个结构支持 subnet_nsg_ids
列表,其中包含一个空字符串。
所以我的问题是有没有办法只循环访问我的 azurerm_subnet_network_security_group_association
资源列表中的特定索引。例如,仅循环遍历 [0] 和 [2],但跳过 [1](因为 [1] 是一个空字符串)
它不像我只需要使用 count
。如果可以进行这种跳过,我也很乐意使用 for_each
。
我不确定我是否完全理解您的问题,但是如果您想在有空字符串时跳过 network_security_group_id
,您可以使用:
network_security_group_id = element(var.subnet_nsg_ids, count.index) != "" ? element(var.subnet_nsg_ids, count.index) : null
如果您想过滤掉包含空字符串的项目,您可以这样做:
for_each = [for idx, val in var.subnet_names): val if var.subnet_nsg_ids[idx] != ""]
我正在尝试更新我现有的 azurerm_subnet
terraform 代码
被许多其他人消耗掉了。所以我们真的不想破坏任何现有的 tfvars
使用 network_security_group_id
的折旧字段从 azurerm_subnet
到名为 azurerm_network_interface_security_group_association
的新资源,从版本 2.0.
现有代码
resource "azurerm_subnet" "generic_subnet" {
count = "${length(var.subnet_names)}"
name = "${element("${var.subnet_names}", count.index)}"
resource_group_name = "${var.resource_group_name}"
virtual_network_name = "${azurerm_virtual_network.generic_vnet.name}"
address_prefix = "${element("${var.subnet_address_ranges}", count.index)}"
service_endpoints = "${var.service_endpoints[count.index]}"
network_security_group_id = "${element(var.subnet_nsg_ids, count.index)}"
route_table_id = "${element(var.subnet_route_tables, count.index)}"
}
tfvars:
subnet_address_ranges = [
"10.102.40.0/22",
"10.102.44.0/24",
"10.102.45.0/25"
]
subnet_names = [
"private-subnet-01",
"public-subnet-01",
"protected-subnet-01"
]
service_endpoints = [
["Microsoft.AzureCosmosDB","Microsoft.KeyVault", "Microsoft.Storage","Microsoft.Sql","Microsoft.AzureActiveDirectory","Microsoft.ContainerRegistry","Microsoft.EventHub","Microsoft.ServiceBus","Microsoft.Web"],
[],
["Microsoft.KeyVault", "Microsoft.Storage"]
]
subnet_nsg_ids = [
"/subscriptions/yyyy/resourceGroups/yyy/providers/Microsoft.Network/networkSecurityGroups/nsg-01",
"",
"/subscriptions/yyyy/resourceGroups/yyy/providers/Microsoft.Network/networkSecurityGroups/nsg-02"
]
更新代码(通过引入 azurerm_network_interface_security_group_association
资源)
resource "azurerm_subnet" "generic_subnet" {
count = "${length(var.subnet_names)}"
name = "${element("${var.subnet_names}", count.index)}"
resource_group_name = "${var.resource_group_name}"
virtual_network_name = "${azurerm_virtual_network.generic_vnet.name}"
address_prefix = "${element("${var.subnet_address_ranges}", count.index)}"
service_endpoints = "${var.service_endpoints[count.index]}"
network_security_group_id = "${element(var.subnet_nsg_ids, count.index)}"
route_table_id = "${element(var.subnet_route_tables, count.index)}"
}
resource "azurerm_subnet_network_security_group_association" "generic_nsg_association" {
count= "${length(var.subnet_nsg_ids)}"
subnet_id = "${element(azurerm_subnet.generic_subnet.*.id, count.index)}"
network_security_group_id = "${element(var.subnet_nsg_ids, count.index)}"
}
显然我的新资源会通过抛出像
这样的错误来破坏所有 tfvarsError: Can not parse "network_security_group_id" as a resource id: Cannot parse Azure ID: parse "": empty url
on ../../../main.tf line 41, in resource "azurerm_subnet_network_security_group_association" "generic_nsg_association": 41: network_security_group_id = "${element(var.subnet_nsg_ids, count.index)}"
原因是我们需要给出 network_security_group_id
参数。但是,我所有现有的 tfvar 都有一个结构支持 subnet_nsg_ids
列表,其中包含一个空字符串。
所以我的问题是有没有办法只循环访问我的 azurerm_subnet_network_security_group_association
资源列表中的特定索引。例如,仅循环遍历 [0] 和 [2],但跳过 [1](因为 [1] 是一个空字符串)
它不像我只需要使用 count
。如果可以进行这种跳过,我也很乐意使用 for_each
。
我不确定我是否完全理解您的问题,但是如果您想在有空字符串时跳过 network_security_group_id
,您可以使用:
network_security_group_id = element(var.subnet_nsg_ids, count.index) != "" ? element(var.subnet_nsg_ids, count.index) : null
如果您想过滤掉包含空字符串的项目,您可以这样做:
for_each = [for idx, val in var.subnet_names): val if var.subnet_nsg_ids[idx] != ""]