【发布时间】:2020-05-25 01:37:26
【问题描述】:
我目前正在编写一些将 Azure 私有 DNS 区域部署到 Azure 中的 Terraform 代码。
我已使用以下代码成功部署了 DNS 区域:
dns_zones = [
"domain1.com",
"domain2.com",
"domain3.com",
]
resource "azurerm_private_dns_zone" "dns_zones" {
for_each = toset(var.dns_zones)
name = each.value
resource_group_name = var.resource_group
}
我的问题是配置区域和虚拟网络之间的链接。我需要遍历 dns_zones 列表并有一个嵌套循环,然后遍历 vnet_links 列表并配置区域上的 vnet 链接。
以下解决方案有效,但它不是很健壮,因为从任一列表中删除配置都会打乱列表的索引号,导致 Terraform 删除并重新创建配置,这不是一个选项:
vnet_links = [
{
"linkName": "name-of-vnet-link1"
"vnetId": "vnet--resource-id-placeholder1"
},{
"linkName": "name-of-vnet-link2"
"vnetId": "vnet--resource-id-placeholder2"
}
]
resource "azurerm_private_dns_zone_virtual_network_link" "vnet_link" {
count = length(setproduct(var.dns_zones, var.vnet_links))
name = element(setproduct(var.dns_zones, var.vnet_links)[count.index], 1).linkName
resource_group_name = var.resource_group
private_dns_zone_name = element(setproduct(var.dns_zones, var.vnet_links)[count.index], 0)
virtual_network_id = element(setproduct(var.dns_zones, var.vnet_links)[count.index], 1).vnetId
}
我发现使用下面的 setproduct() 函数可以创建一个包含我想要使用的数据的新列表,我打算将它与 for_each 一起使用而不是计数,但不可能使用this 与 toset() 函数一起使用,因为它只接受字符串列表。
setproduct(var.dns_zones, var.vnet_links)
现在我有点不知道该去哪里。我可以在 vnet_links 列表中包含区域信息,但这需要我想避免的大量重复。理想情况下,我希望能够找到一个不需要对 dns_zones 列表进行任何更改的解决方案,并保留一个包含 vnet 链接的单独列表。
谢谢!
编辑:
感谢 Charles 提供了一种格式化数据的方法。除了 Charles 响应之外,我还需要在 for_each 循环中创建一个动态映射来使用数据。最终解决方案如下:
dns_zones = [
"domain1.com",
"domain2.com",
"domain3.com",
]
vnet_links = [
{
"linkName": "name-of-vnet-link1"
"vnetId": "vnet--resource-id-placeholder1"
},{
"linkName": "name-of-vnet-link2"
"vnetId": "vnet--resource-id-placeholder2"
}
]
locals {
association = flatten([
for dns_zone in var.dns_zones: [
for link in var.vnet_links: {
zone = dns_zone
vnet_link = link
}
]
])
}
resource "azurerm_private_dns_zone_virtual_network_link" "vnet_link" {
for_each = { for row in local.association:
"${row.zone}_${row.vnet_link.linkName}" => {
zone = row.zone
linkName = row.vnet_link.linkName
vnetId = row.vnet_link.vnetId
}
}
name = each.value.linkName
resource_group_name = var.resource_group
private_dns_zone_name = each.value.zone
virtual_network_id = each.value.vnetId
}
【问题讨论】: