Azure Policy自定义NSG规则部署报无效部署错误,求排查代码问题
Azure Policy自定义NSG规则部署失败问题排查
以下是你提供的Azure Policy代码中存在的核心问题:
1. 部署模板Schema不匹配
你使用了订阅级部署模板的Schema,但NSG属于资源组级别资源,对应的部署模板Schema应使用资源组版本:
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#"
错误的Schema会导致部署上下文不匹配,触发"Invalid Deployment"错误。
2. 部署模板参数定义错误且冗余
- 模板中定义了
rulename、access等大量参数,但实际资源配置完全硬编码,未引用任何参数,属于无效定义; nsgName参数定义格式错误:参数不能直接在定义中写入[field('name')],需先定义参数类型,再在部署的parameters节点传递值。
3. ExistenceCondition写法冗余易出错
你在existenceCondition的where条件中使用嵌套的equals(true, value: [equals(...)])写法,可简化为直接比较字段与参数,既简洁又避免逻辑错误:
{ "equals": "[parameters('sourcePortRange')]", "field": "Microsoft.Network/networkSecurityGroups/securityRules[*].sourcePortRange" }
4. 部署未传递必要参数
在deployment节点中,未为模板参数传递值,不符合ARM模板执行要求,会导致部署上下文缺失。
修复后的完整Policy代码
{ "policyType": "Custom", "description": "This policy deploys a default Deny All rule to a newly deployed NSG, if it doesn't already exist in the NSG.", "mode": "Indexed", "displayName": "NSG default Inbound Deny All", "parameters": { "access": { "type": "String", "metadata": { "description": "The network traffic should be denied.", "displayName": "access" }, "defaultValue": "Deny" }, "destinationAddressPrefix": { "type": "String", "metadata": { "description": "The destination address prefix. CIDR or destination IP range. Asterisk '*' can also be used to match all source IPs. Default tags such as 'VirtualNetwork', 'AzureLoadBalancer' and 'Internet' can also be used.", "displayName": "destinationAddressPrefix" }, "defaultValue": "*" }, "destinationPortRange": { "type": "String", "metadata": { "description": "The destination port or range. Integer or range between 0 and 65535. Asterisk '*' can also be used to match all ports.", "displayName": "destinationPortRange" }, "defaultValue": "*" }, "direction": { "type": "String", "metadata": { "description": "The direction of the rule. The direction specifies if rule will be evaluated on incoming or outgoing traffic. - Inbound or Outbound", "displayName": "direction" }, "defaultValue": "Inbound" }, "effect": { "type": "String", "metadata": { "description": "The effect determines what happens when the policy rule is evaluated to match", "displayName": "Effect" }, "defaultValue": "deployIfNotExists" }, "protocol": { "type": "String", "metadata": { "description": "Network protocol this rule applies to. - Tcp, Udp, Icmp, Esp, *", "displayName": "protocol" }, "defaultValue": "*" }, "sourceAddressPrefix": { "type": "String", "metadata": { "description": "The CIDR or source IP range. Asterisk '*' can also be used to match all source IPs. Default tags such as 'VirtualNetwork', 'AzureLoadBalancer' and 'Internet' can also be used. If this is an ingress rule, specifies where network traffic originates from.", "displayName": "sourceAddressPrefix" }, "defaultValue": "*" }, "sourcePortRange": { "type": "String", "metadata": { "description": "The source port or range. Integer or range between 0 and 65535. Asterisk '*' can also be used to match all ports.", "displayName": "sourcePortRange" }, "defaultValue": "*" } }, "policyRule": { "if": { "equals": "Microsoft.Network/networkSecurityGroups", "field": "type" }, "then": { "details": { "type": "Microsoft.Network/networkSecurityGroups/securityRules", "existenceCondition": { "count": { "field": "Microsoft.Network/networkSecurityGroups/securityRules[*]", "where": { "allOf": [ { "equals": "[parameters('protocol')]", "field": "Microsoft.Network/networkSecurityGroups/securityRules[*].protocol" }, { "equals": "[parameters('sourcePortRange')]", "field": "Microsoft.Network/networkSecurityGroups/securityRules[*].sourcePortRange" }, { "equals": "[parameters('destinationPortRange')]", "field": "Microsoft.Network/networkSecurityGroups/securityRules[*].destinationPortRange" }, { "equals": "[parameters('sourceAddressPrefix')]", "field": "Microsoft.Network/networkSecurityGroups/securityRules[*].sourceAddressPrefix" }, { "equals": "[parameters('destinationAddressPrefix')]", "field": "Microsoft.Network/networkSecurityGroups/securityRules[*].destinationAddressPrefix" }, { "equals": "[parameters('access')]", "field": "Microsoft.Network/networkSecurityGroups/securityRules[*].access" }, { "equals": "[parameters('direction')]", "field": "Microsoft.Network/networkSecurityGroups/securityRules[*].direction" } ] } }, "notEquals": 0 }, "deployment": { "properties": { "mode": "incremental", "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", "parameters": { "nsgName": { "type": "String" } }, "resources": [ { "type": "Microsoft.Network/networkSecurityGroups/securityRules", "apiVersion": "2022-05-01", "name": "[concat(parameters('nsgName'), '/Default DenyAnyAnyInbound')]", "properties": { "protocol": "*", "sourcePortRange": "*", "destinationPortRange": "*", "sourceAddressPrefix": "*", "destinationAddressPrefix": "*", "access": "Deny", "priority": 4089, "direction": "Inbound", "sourcePortRanges": [], "destinationPortRanges": [], "sourceAddressPrefixes": [], "destinationAddressPrefixes": [], "description": "Managed deny rule" } } ] }, "parameters": { "nsgName": { "value": "[field('name')]" } } } }, "roleDefinitionIds": [ "/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7" ] }, "effect": "[parameters('effect')]" } } }
修复后,该Policy可正确为新部署的NSG添加指定的Deny All规则,同时对现有不符合要求的NSG执行修复操作。
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

