天蓝色的政策如果条件,不能有 2 种资源类型?

azure policy if condition, can not have 2 resource types?

我正在编写一个简单的策略,如果它是 Azure PaaS SQL,并且在防火墙规则中有 public 个 IP,它将进行评估。

{
    "mode": "All",
    "policyRule": {
        "if": {
            "allOf": [
                {
                    "field": "type",
                    "equals": "Microsoft.Sql/servers"
                },
                {
                    "allOf": [
                        {
                            "field": "Microsoft.Sql/servers/firewallRules/startIpAddress",
                            "equals": "xxx.xxx.xxx.xxx"
                        },
                        {
                            "field": "Microsoft.Sql/servers/firewallRules/endIpAddress",
                            "equals": "xxx.xxx.xxx.xxx"
                        }
                    ]
                }
            ]
        },
        "then": {
            "effect": "[parameters('effect')]"
            
    },
    "parameters": {
        "effect": {
            "type": "String",
            "metadata": {
                "displayName": "Effect",
                "description": "Enable or disable the execution of the policy"
            },
            "allowedValues": [
                "Disabled",
                "Audit"
            ],
            "defaultValue": "Audit"
        }
    }
}

我发现当我点击添加这个定义时,错误信息告诉我

Editing policy definition 'sql firewall audit' in 'RogerBlueprint' failed. 
The policy definition  targets multiple resource types, but the policy rule is authored in a way that makes the policy not applicable to the target resource types 'Microsoft.Sql/servers,Microsoft.Sql/servers/firewallRules'. 
This is because the policy rule has a condition that can never be satisfied by the target resource types. 
If an alias is used, please make sure that the alias gets evaluated against only the resource type it belongs to by adding a type condition before it, or split the policy into multiple ones to avoid targeting multiple resource types.

请问在IF条件下,是不是不能同时使用两种资源类型?

确实如此 - 从 ARM 的角度来看,Microsoft.Sql/serversMicrosoft.Sql/servers/firewallRules 是两个不同的对象,即使存在父 <> 子关系。

策略引擎的运行方式是逐一扫描每一个ARM组件。在您的情况下,它清楚地表明它不会成功,因为给定对象不能是同一类型的两种类型。在幕后,别名 Microsoft.Sql/servers/firewallRules 被识别为 type 而不是 property.

如果逻辑适用于给定范围内的所有服务器,那么您可以将策略集中在 Microsoft.Sql/servers/firewallRules :

{
    "mode": "All",
    "policyRule": {
        "if": {
            "allOf": [
                {
                    "field": "type",
                    "equals": "Microsoft.Sql/servers/firewallRules"
                },
                {
                    "allOf": [
                        {
                            "field": "Microsoft.Sql/servers/firewallRules/startIpAddress",
                            "equals": "xxx.xxx.xxx.xxx"
                        },
                        {
                            "field": "Microsoft.Sql/servers/firewallRules/endIpAddress",
                            "equals": "xxx.xxx.xxx.xxx"
                        }
                    ]
                }
            ]
        },
        "then": {
            "effect": "[parameters('effect')]"
            
    },
    "parameters": {
        "effect": {
            "type": "String",
            "metadata": {
                "displayName": "Effect",
                "description": "Enable or disable the execution of the policy"
            },
            "allowedValues": [
                "Disabled",
                "Audit"
            ],
            "defaultValue": "Audit"
        }
    }
}