我正在尝试使用Terraform 0.12+及其新的for_each在Azure中构建多个vnet,并遇到一些麻烦。我希望新功能可以使我创建一个通用的网络模块,该模块接受一个复杂的变量,但是我可能已经达到了极限,或者只是没有正确地考虑它。 本质上,我的变量的构建方式类似于
variable "networks" {
type = list(object({ name = string, newbits = number, netnum = number, subnets = list(object({ name = string, newbits = number, netnum = number}))}))
}
您可以看到它是一个网络阵列,其中包含该网络的子网的子阵列。通过这种方式,可以轻松记录网络,而无需增加地形资源需求,因此我们的网络团队可以轻松地进行调整/扩展,而不必担心了解HCL。
我可以使用count及其索引来执行构建多个vnet资源的必要功能,但是我想使用for_each,因为它允许索引密钥而不是随时间变化的计数(需要重新部署)这是我们做不到的。
网络对象
networks = [
{
# x.x.1.0/24
name = "DMZ",
newbits = "8",
netnum = "1",
subnets = [
{
# x.x.1.0/25
name = "DMZ"
newbits = "9",
netnum = "2"
}
]
},
{
# x.x.33.0/24
name = "Intermediary"
newbits = "8",
netnum = "33",
subnets = [
{
# x.x.33.0/25
name = "subnet1"
newbits = "9",
netnum = "66"
},
{
# x.x.33.128/25
name = "subnet2"
newbits = "9",
netnum = "67"
}
]
}
]
我通过将对象更改为映射,然后使用each.key和each.value(为each.value做一个cidrsubnet),尝试并成功地使用for_each构建了vnet,但是问题在于制作子网。
locals {
vnets = {
for vnet in var.networks:
vnet.name => cidrsubnet(var.root_cidr, vnet.newbits, vnet.netnum)
}
}
由于该地图不包含那些子网,因此我只是将头撞在墙上。 有没有人有什么建议?还是当我不需要的时候,我真的把它变得太复杂了吗?
有效的资源创建,但是没有子网
resource "azurerm_virtual_network" "vnets" {
for_each = local.vnets
name = each.key
address_space = [each.value]
location = azurerm_resource_group.network.location
resource_group_name = azurerm_resource_group.network.name
}
我希望可以使用动态块,并可能对其进行过滤以匹配网络资源内部的each.key。之后,我也尝试使用其自己的子网资源来执行此操作,但无法弄清楚。
这是我希望可以使用的全部资源
resource "azurerm_virtual_network" "vnets" {
for_each = local.vnets
name = "99999-Nucleus-${each.key}"
address_space = [each.value]
location = azurerm_resource_group.network.location
resource_group_name = azurerm_resource_group.network.name
dynamic "subnet" {
for_each = [for vnet in var.networks:
[for s in vnet.subnets: {
name = s.name
prefix = cidrsubnet(var.root_cidr, s.newbits, s.netnum)
}] if var.networks.name == each.key]
content {
name = subnet.value.name
address_prefix = subnet.value.prefix
}
}
}
答案 0 :(得分:1)
在此处构造此中间local.vnets
映射会使此问题更难解决,因为它会丢弃这些对象中的所有其他信息,从而使{{1 }}块。
相反,如果我们对原始resource "azurerm_virtual_network" "vnets"
值使用重复,那么我们可以直接从var.networks
内部获得subnets
列表:
each.value