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

已配置NSG仍触发Azure策略限制,Bicep子网部署失败求助

问题:已配置子网关联NSG仍触发Azure策略阻止

用户采用多层Bicep文件架构,通过PowerShell脚本调用az deployment mg what-if执行管理组级部署,已在parSubnets参数中配置了关联指定NSG的子网,但部署时仍触发名为**"子网必须关联网络安全组"**的Azure策略限制,提示资源vnet-02-prod被策略阻止。

相关代码与信息

PowerShell脚本片段

$TEMPLATEFILE="./infra-as-code/bicep/orchestration/hubPeeredSpoke/hubPeeredSpoke.bicep"
Write-Host $paramsJson

$updatedParamsJson = $updatedParamsJson.Replace('"', '\"')
if ($action -eq "whatif") {
    az deployment mg what-if --name $NAME --location $LOCATION --management-group-id $MGID --template-file $TEMPLATEFILE --parameters "$paramsJson" --debug
}

参数JSON输出

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "parAllowSpokeForwardedTraffic": {
      "value": false
    },
    "parSpokeNetworkName": {
      "value": "vnet-02-prod"
    },
    "parSubnets": {
      "value": [
        {
          "name": "sub-001-prod",
          "privateEndpointNetworkPolicies": "Disabled",
          "privateLinkServiceNetworkPolicies": "Enabled",
          "addressPrefix": "100.100.100.90/24",
          "networkSecurityGroup": {
            "id": "/subscriptions/xxxxxx/resourceGroups/rg-prod-001/providers/Microsoft.Network/networkSecurityGroups/nsg-001"
          },
          "delegations": [
            {
              "name": "private",
              "serviceName": "Microsoft.Databricks/workspaces"
            }
          ]
        }
      ]
    }
  }
}

hubPeeredSpoke.bicep片段

param parSubnets array = []
module modSpokeNetworking '../../modules/spokeNetworking/spokeNetworking.bicep' = {
  scope: resourceGroup(parPeeredVnetSubscriptionId, parResourceGroupNameForSpokeNetworking)
  name: varModuleDeploymentNames.modSpokeNetworking
  dependsOn: [
    modResourceGroup
  ]
  params: {
    parSpokeNetworkName: parSpokeNetworkName
    parSpokeNetworkAddressPrefix: parSpokeNetworkAddressPrefix
    parDdosProtectionPlanId: parDdosProtectionPlanId
    parDnsServerIps: parDnsServerIps
    parNextHopIpAddress: varNextHopIPAddress
    parSpokeToHubRouteTableName: parSpokeToHubRouteTableName
    parDisableBgpRoutePropagation: parDisableBgpRoutePropagation
    parTags: parTags
    parTelemetryOptOut: parTelemetryOptOut
    parLocation: parLocation
    parSubnets: parSubnets
  }
}

spokeNetworking.bicep片段

param parSubnets array = []
resource resSpokeVirtualNetwork 'Microsoft.Network/virtualNetworks@2023-02-01' = {
  name: parSpokeNetworkName
  location: parLocation
  tags: parTags
  properties: {
    addressSpace: {
      addressPrefixes: [
        parSpokeNetworkAddressPrefix
      ]
    }
    enableDdosProtection: (!empty(parDdosProtectionPlanId)? true : false)
    ddosProtectionPlan: (!empty(parDdosProtectionPlanId)? true : false)? {
      id: parDdosProtectionPlanId
    } : null
    dhcpOptions: (!empty(parDnsServerIps)? true : false)? {
      dnsServers: parDnsServerIps
    } : null
    subnets: parSubnets
  }
}

报错信息

RequestDisallowedByPolicy - 资源 'vnet-02-prod' 被策略阻止。策略标识符: '[{"policyAssignment":{"name":"子网必须关联网络安全组","id":"/providers/Microsoft.Management/managementGroups/landingzones/alz/providers/Microsoft.Authorization/policyAssignments/Deny-Subnet-Without-Nsg"},"policyDefinition":{"name":"子网必须关联网络安全组","id":"/providers/Microsoft.Management/managementGroups/landingzones/alz/providers/Microsoft.Authorization/policyDefinitions/Deny-Subnet-Without-Nsg"}}]'。

排查与解决方法

1. 拆分子网资源定义,明确部署顺序

当前Bicep将子网作为VNet的嵌套属性传入,策略评估可能在VNet创建时无法正确识别子网的NSG关联。将子网拆分为独立资源,显式绑定NSG:

修改spokeNetworking.bicep:

param parSubnets array = []
resource resSpokeVirtualNetwork 'Microsoft.Network/virtualNetworks@2023-02-01' = {
  name: parSpokeNetworkName
  location: parLocation
  tags: parTags
  properties: {
    addressSpace: {
      addressPrefixes: [
        parSpokeNetworkAddressPrefix
      ]
    }
    enableDdosProtection: (!empty(parDdosProtectionPlanId)? true : false)
    ddosProtectionPlan: (!empty(parDdosProtectionPlanId)? true : false)? {
      id: parDdosProtectionPlanId
    } : null
    dhcpOptions: (!empty(parDnsServerIps)? true : false)? {
      dnsServers: parDnsServerIps
    } : null
  }
}

// 单独定义子网资源,显式关联NSG
resource resSubnets 'Microsoft.Network/virtualNetworks/subnets@2023-02-01' = [for subnet in parSubnets: {
  parent: resSpokeVirtualNetwork
  name: subnet.name
  properties: {
    addressPrefix: subnet.addressPrefix
    privateEndpointNetworkPolicies: subnet.privateEndpointNetworkPolicies
    privateLinkServiceNetworkPolicies: subnet.privateLinkServiceNetworkPolicies
    networkSecurityGroup: subnet.networkSecurityGroup
    delegations: subnet.delegations
  }
}]

2. 验证NSG ID有效性与部署权限

  • 执行以下命令确认NSG存在:
    az network nsg show --ids "/subscriptions/xxxxxx/resourceGroups/rg-prod-001/providers/Microsoft.Network/networkSecurityGroups/nsg-001"
    
  • 检查部署所用身份(用户/服务主体)是否拥有该NSG的Microsoft.Network/networkSecurityGroups/read权限,避免策略评估时无法解析NSG资源。

3. 优化参数类型约束,确保属性传递正确

在spokeNetworking.bicep中为parSubnets参数添加明确的类型约束,避免参数传递过程中属性丢失或格式错误:

param parSubnets array = [
  {
    name: string
    addressPrefix: string
    privateEndpointNetworkPolicies: string
    privateLinkServiceNetworkPolicies: string
    networkSecurityGroup: {
      id: string
    }
    delegations: array
  }
]

4. 检查策略定义的具体规则

查看策略的详细规则,确认是否存在额外约束(如NSG与子网同资源组、NSG包含特定规则等):

az policy definition show --id "/providers/Microsoft.Management/managementGroups/landingzones/alz/providers/Microsoft.Authorization/policyDefinitions/Deny-Subnet-Without-Nsg"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:20:29