You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何自动关联Azure专用链接DNS区域与私有端点groupIds

自动化生成Azure DNS区域组强制策略的groupId映射需求

背景

我正在公司Azure租户中配置混合DNS,要创建微软文档中提到的DNS区域组强制策略。手动配置虽然快速,但长期来看自动化方案更便于维护。

当前Terraform配置

我已通过Terraform批量部署专用DNS区域,相关配置如下:

私有DNS区域变量定义

variable "private_link_private_dns_zones" {
  type = map(object({
    zone_name = optional(string, null)
  }))
  default = {
    azure_ml = {
      zone_name = "privatelink.api.azureml.ms"
    }
    azure_ml_notebooks = {
      zone_name = "privatelink.notebooks.azure.net"
    }
    azure_ai_cog_svcs = {
      zone_name = "privatelink.cognitiveservices.azure.com"
    }
    azure_ai_oai = {
      zone_name = "privatelink.openai.azure.com"
    }
    azure_bot_svc_bot = {
      zone_name = "privatelink.directline.botframework.com"
    }
    azure_bot_svc_token = {
      zone_name = "privatelink.token.botframework.com"
    }
    # ... 其他DNS区域
  }
}

私有DNS区域资源部署

resource "azurerm_private_dns_zone" "core_dns_zone" {
  for_each = var.private_link_private_dns_zones

  name                = each.value.zone_name
  resource_group_name = var.resource_group_name

  tags = var.tags

  lifecycle { # 等待微软修复ARM API的标签异常行为
    ignore_changes = [
      tags
    ]
  }
}

输出区域ID映射

output "zone_mapping" {
  value = {
    for zone in azurerm_private_dns_zone.core_dns_zone[*] :
        zone.name => zone.id
  }
}

核心需求

策略需要将私有端点的groupIds属性与对应值匹配,以关联正确的专用DNS区域。我希望结合现有输出和其他数据源,生成如下格式的对象:

ideal_output = {
     service_a = {
      zone_name = "privatelink.service_a.windows.net"
      zone_id = "/subscriptions/1234/resourceGroups/rg-foo/providers/Microsoft.Network/privateDnsZones/privatelink.service_a.windows.net"
      groupId_to_match = "service"
   }
}

通过该对象可批量创建所有策略,示例配置如下:

resource "azurerm_policy_definition" "dns_zone_dine_policy" {
  for_each = var.ideal_output

  name         = "DeployIfNotExists - ${upper(each.key)} DNS Group"
  display_name = "DeployIfNotExists - ${upper(each.key)} DNS Group"
  mode         = "Indexed"
  policy_type  = "Custom"

  policy_rule = jsonencode({
    if = {
      allOf = [
        {
          field  = "type"
          equals = "Microsoft.Network/privateEndpoints"
        },
        {
          count = {
            field = "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*].groupIds[*]"
            where = {
              field  = "Microsoft.Network/privateEndpoints/privateLinkServiceConnections[*].groupIds[*]"
              equals = each.value["groupId_to_match"]
            }
          },
          greaterOrEquals = 1
        }
      ]
    },
    then = {
      effect = "deployIfNotExists",
      details = {
        type = "Microsoft.Network/privateEndpoints/privateDnsZoneGroups"
        roleDefinitionIds = [
          "/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7"
        ]
        deployment = {
          properties = {
            mode = "incremental"
            template = {
              "$schema"      = "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"
              contentVersion = "1.0.0.0"
              parameters = {
                privateEndpointName = {
                  type = "string"
                }
                location = {
                  type = "string"
                }
              }
              resources = [
                {
                  name       = "[concat(parameters('privateEndpointName'), '/deployedByPolicy')]"
                  type       = "Microsoft.Network/privateEndpoints/privateDnsZoneGroups"
                  apiVersion = "2020-03-01"
                  location   = "[parameters('location')]"
                  properties = {
                    privateDnsZoneConfigs = [
                      {
                        name = each.key
                        properties = {
                          privateDnsZoneId = each.value["zone_id"]
                        }
                      }
                    ]
                  }
                }
              ]
            }
            parameters = {
              privateEndpointName = {
                value = "[field('name')]"
              }
              location = {
                value = "[field('location')]"
              }
            }
          }
        }
      }
    }
  })
}

请问是否可以无需手动从微软文档复制groupId_to_match的值来实现这个需求?手动方式可行,但长期会增加维护的手动工作量。

内容的提问来源于stack exchange,提问作者Gabriel Kelly

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 05:07:09