问题描述
我正在尝试为应用程序网关创建策略。该政策如下所述
Http侦听器不应附加到公共IP前端配置
因此,据我了解,我必须检查 frontendConfiguration 是否具有公共IP,然后检查是否在任何 httpListeners中引用了公共IP的名称
由于frontendIPConfigurations和httpListeners都是数组,因此我考虑对此复杂查询使用计数,并尝试了以下方法
"if": {
"count": {
"field": "Microsoft.Network/applicationGateways/frontendIPConfigurations[*]","where": {
"allOf": [
{
"field": "Microsoft.Network/applicationGateways/frontendIPConfigurations[*].publicIPAddress.id","exists": true
},{
"field": "Microsoft.Network/applicationGateways/httpListeners[*].frontendIPConfiguration.id","like": "[concat('*',field('Microsoft.Network/applicationGateways/frontendIPConfigurations[*].publicIPAddress.name'))]"
}
]
}
},"greaterOrEquals": 1
},
但是我收到以下错误
在'count.where'表达式内使用的别名:'Microsoft.Network/applicationGateways/httpListeners[].frontendIPConfiguration.id'指向计数范围之外的数组:'Microsoft.Network/applicationGateways/ frontendIPConfigurations []'
能不能解决这个问题?
以下是示例ARM模板供参考:
{
"$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#","contentVersion": "1.0.0.0","parameters": {
"location": {
"type": "string"
},"applicationGatewayName": {
"type": "string"
},"tier": {
"type": "string"
},"skuSize": {
"type": "string"
},"capacity": {
"type": "int","defaultValue": 2
},"subnetName": {
"type": "string"
},"zones": {
"type": "array"
},"virtualNetworkName": {
"type": "string"
},"virtualNetworkPrefix": {
"type": "array"
},"publicIpAddressName": {
"type": "string"
},"sku": {
"type": "string"
},"allocationMethod": {
"type": "string"
},"publicIpZones": {
"type": "array"
},"privateIpAddress": {
"type": "string"
},"autoScaleMaxCapacity": {
"type": "int"
}
},"variables": {
"vnetId": "[resourceId('policy-tester','Microsoft.Network/virtualNetworks/',parameters('virtualNetworkName'))]","publicIPRef": "[resourceId('Microsoft.Network/publicIPAddresses/',parameters('publicIpAddressName'))]","subnetRef": "[concat(variables('vnetId'),'/subnets/',parameters('subnetName'))]","applicationGatewayId": "[resourceId('Microsoft.Network/applicationGateways',parameters('applicationGatewayName'))]"
},"resources": [
{
"name": "[parameters('applicationGatewayName')]","type": "Microsoft.Network/applicationGateways","apiVersion": "2019-09-01","location": "[parameters('location')]","zones": "[parameters('zones')]","dependsOn": [
"[concat('Microsoft.Network/virtualNetworks/',"[concat('Microsoft.Network/publicIPAddresses/',parameters('publicIpAddressName'))]"
],"tags": {},"properties": {
"sku": {
"name": "[parameters('skuSize')]","tier": "[parameters('tier')]"
},"gatewayIPConfigurations": [
{
"name": "appGatewayIpConfig","properties": {
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
],"frontendIPConfigurations": [
{
"name": "appGwPrivateFrontendIp","properties": {
"subnet": {
"id": "[variables('subnetRef')]"
},"privateIPAddress": "[parameters('privateIpAddress')]","privateIPAllocationMethod": "Static"
}
},{
"name": "appGwPublicFrontendIp","properties": {
"PublicIPAddress": {
"id": "[variables('publicIPRef')]"
}
}
}
],"frontendPorts": [
{
"name": "port_80","properties": {
"Port": 80
}
},{
"name": "port_8080","properties": {
"Port": 8080
}
}
],"backendAddresspools": [
{
"name": "samplebend","properties": {
"backendAddresses": []
}
}
],"backendHttpSettingsCollection": [
{
"name": "sample-http","properties": {
"Port": 80,"Protocol": "Http","cookieBasedAffinity": "disabled","requestTimeout": 20
}
}
],"httpListeners": [
{
"name": "sample-list","properties": {
"frontendIPConfiguration": {
"id": "[concat(variables('applicationGatewayId'),'/frontendIPConfigurations/appGwPublicFrontendIp')]"
},"frontendPort": {
"id": "[concat(variables('applicationGatewayId'),'/frontendPorts/port_80')]"
},"protocol": "Http","sslCertificate": null
}
},{
"name": "sample-priv-http",'/frontendIPConfigurations/appGwPrivateFrontendIp')]"
},'/frontendPorts/port_8080')]"
},"sslCertificate": null
}
}
],"requestRoutingRules": [
{
"Name": "sample-rule","properties": {
"RuleType": "Basic","httpListener": {
"id": "[concat(variables('applicationGatewayId'),'/httpListeners/sample-list')]"
},"backendAddresspool": {
"id": "[concat(variables('applicationGatewayId'),'/backendAddresspools/samplebend')]"
},"backendHttpSettings": {
"id": "[concat(variables('applicationGatewayId'),'/backendHttpSettingsCollection/sample-http')]"
}
}
},{
"Name": "sample-priv-http-rule",'/httpListeners/sample-priv-http')]"
},'/backendHttpSettingsCollection/sample-http')]"
}
}
}
],"enableHttp2": false,"sslCertificates": [],"probes": [],"autoscaleConfiguration": {
"minCapacity": "[parameters('capacity')]","maxCapacity": "[parameters('autoScaleMaxCapacity')]"
}
}
},{
"apiVersion": "2019-09-01","type": "Microsoft.Network/virtualNetworks","name": "[parameters('virtualNetworkName')]","properties": {
"addressspace": {
"addressprefixes": "[parameters('virtualNetworkPrefix')]"
},"subnets": [
{
"name": "default","properties": {
"addressprefix": "10.0.0.0/24"
}
}
]
}
},{
"apiVersion": "2019-02-01","type": "Microsoft.Network/publicIPAddresses","name": "[parameters('publicIpAddressName')]","sku": {
"name": "[parameters('sku')]"
},"zones": "[parameters('publicIpZones')]","properties": {
"publicIPAllocationMethod": "[parameters('allocationMethod')]"
}
}
]
}
解决方法
免责声明:我为 Microsoft 工作,但这不是官方答案
以下政策应该可以解决问题:
{
"if": {
"allOf": [
{
"field": "type","equals": "Microsoft.Network/applicationGateways"
},{
"count": {
"field": "Microsoft.Network/applicationGateways/frontendIPConfigurations[*]","where": {
"allOf": [
{
"field": "Microsoft.Network/applicationGateways/frontendIPConfigurations[*].publicIPAddress.id","exists": true
},{
"value": "[format('{0}/frontendIPConfigurations/{1}',field('id'),current('Microsoft.Network/applicationGateways/frontendIPConfigurations[*].name'))]","in": "[field('Microsoft.Network/applicationGateways/httpListeners[*].frontendIPConfiguration.id')]"
}
]
}
},"greater": 0
}
]
},"then": {
"effect": "deny"
}
}
详情
条件:
{
"value": "[format('{0}/frontendIPConfigurations/{1}',"in": "[field('Microsoft.Network/applicationGateways/httpListeners[*].frontendIPConfiguration.id')]"
}
检查当前 frontendIPConfiguration(具有公共 IP)的资源 ID 是否被任何 httpListeners 引用。
value
表达式通过组合应用 GW 资源的资源 ID + 当前 frontendIPConfiguration 资源的名称来构建当前正在评估的 frontendIPConfiguration 的资源 ID。我们必须从头开始构建它,因为在创建新的应用程序 gw 资源时,frontendIPConfiguration 的 id
属性不存在于请求内容中。
另请注意,当您想要访问由 count
表达式枚举的当前数组成员的值时,您需要 should use the current()
function instead of field()
。
关于你遇到的错误信息,这是因为表达式:
{
"field": "Microsoft.Network/applicationGateways/httpListeners[*].frontendIPConfiguration.id","like": "[concat('*',field('Microsoft.Network/applicationGateways/frontendIPConfigurations[*].publicIPAddress.name'))]"
}
隐式检查Microsoft.Network/applicationGateways/httpListeners[*].frontendIPConfiguration.id
的所有值是否与条件匹配(请参阅here)。这基本上是计数表达式的一种不同形式,正如错误消息所说,您无法从枚举不同数组的表达式内部枚举一个数组。