简体   繁体   中英

Azure Policy Invalid Deployment

I am testing around with Azure Policy for my first time. And I had read through the documentation for structure, and effects, and all that stuff. I also found a custom policy which fit my scenario : Adding a nsg rule to all new NSGs

Now, that Github policy doesn't actually work. When remediating existing NSG's there comes the error Invalid Deployment - as if the template in it is incorrect. However, when cross-checking the template with a re-deployment of a NSG where I add a rule myself, it looks to me like the code lines up.

My current code for the policy looks like this:

{
    "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": true,
                                    "value": "[equals(field('Microsoft.Network/networkSecurityGroups/securityRules[*].sourcePortRange'), parameters('sourcePortRange'))]"
                                },
                                {
                                    "equals": true,
                                    "value": "[equals(field('Microsoft.Network/networkSecurityGroups/securityRules[*].destinationPortRange'), parameters('destinationPortRange'))]"
                                },
                                {
                                    "equals": true,
                                    "value": "[equals(field('Microsoft.Network/networkSecurityGroups/securityRules[*].sourceAddressPrefix'), parameters('sourceAddressPrefix'))]"
                                },
                                {
                                    "equals": true,
                                    "value": "[equals(field('Microsoft.Network/networkSecurityGroups/securityRules[*].destinationAddressPrefix'), parameters('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": "http://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
                            "contentVersion": "1.0.0.0",
                            "parameters": {
                                "rulename": {
                                    "type": "String"
                                },
                                "access": {
                                    "type": "String"
                                },
                                "description": {
                                    "type": "String"
                                },
                                "destinationAddressPrefix": {
                                    "type": "Array"
                                },
                                "destinationPortRange": {
                                    "type": "Array"
                                },
                                "direction": {
                                    "type": "String"
                                },
                                "priority": {
                                    "type": "Integer"
                                },
                                "protocol": {
                                    "type": "String"
                                },
                                "sourceAddressPrefix": {
                                    "type": "Array"
                                },
                                "sourcePortRange": {
                                    "type": "Array"
                                },
                                "nsgName": "[field('name')]"                            },
                            "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"
                                    }
                                }
                            ]
                        }
                    }
                },
                "roleDefinitionIds": [
                    "/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7"
                ]
            },
            "effect": "[parameters('effect')]"
        }
    }
}

Can anyone tell me what is wrong with the code?

PS: Mind you, my goal of updating newly deployed NSGs with a proper nsg rule isn't achieved with this policy. I expect though, that if the remediation works; The goal would be achieved as well...

You get to see non-compliant resources, which means the if and existenceCondition are working. This is confirmed by the error message:
"The deployment definition is invalid. Please see https://aka.ms/arm-deploy for usage details."

Multi things are wrong and can be optimized.
You are use the subscription deployment schema instead of:
https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#
See more here:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/syntax#template-format

You cannot have space in your name:
"name": "[concat(parameters('nsgName'), '/Default DenyAnyAnyInbound')]",
"The name must begin with a letter or number, end with a letter, number or underscore, and may contain only letters, numbers, underscores, periods, or hyphens."

Good practice to use latest API now that you use a custom policy:
"apiVersion": "2022-07-01"

Then lastly, you had a bunched of unused parameters.
"nsgName": "[field('name')]" is not defined as a parameter , and where it is currently written should be the type ( string ).

{
"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": {
        "effect": "[parameters('effect')]",
        "details": {
            "type": "Microsoft.Network/networkSecurityGroups/securityRules",
            "roleDefinitionIds": [
                "/providers/Microsoft.Authorization/roleDefinitions/4d97b98b-1d4f-4787-a291-c67834d212e7"
            ],
            "existenceCondition": {
                "count": {
                    "field": "Microsoft.Network/networkSecurityGroups/securityRules[*]",
                    "where": {
                        "allOf": [
                            {
                                "equals": "[parameters('protocol')]",
                                "field": "Microsoft.Network/networkSecurityGroups/securityRules[*].protocol"
                            },
                            {
                                "equals": true,
                                "value": "[equals(field('Microsoft.Network/networkSecurityGroups/securityRules[*].sourcePortRange'), parameters('sourcePortRange'))]"
                            },
                            {
                                "equals": true,
                                "value": "[equals(field('Microsoft.Network/networkSecurityGroups/securityRules[*].destinationPortRange'), parameters('destinationPortRange'))]"
                            },
                            {
                                "equals": true,
                                "value": "[equals(field('Microsoft.Network/networkSecurityGroups/securityRules[*].sourceAddressPrefix'), parameters('sourceAddressPrefix'))]"
                            },
                            {
                                "equals": true,
                                "value": "[equals(field('Microsoft.Network/networkSecurityGroups/securityRules[*].destinationAddressPrefix'), parameters('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",
                    "parameters": {
                        "nsgName": {
                            "value": "[field('name')]"
                        }
                    },
                    "template": {
                        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
                        "contentVersion": "1.0.0.0",
                        "parameters": {
                            "nsgName": {
                                "type": "string"
                            }
                        },
                        "resources": [
                            {
                                "name": "[concat(parameters('nsgName'),'/DenyAnyInbound')]",
                                "type": "Microsoft.Network/networkSecurityGroups/securityRules",
                                "apiVersion": "2022-07-01",
                                "properties": {
                                    "description": "Managed deny rule",
                                    "access": "Deny",
                                    "direction": "Inbound",
                                    "priority": 4000,
                                    "protocol": "*",
                                    "sourcePortRange": "*",
                                    "sourceAddressPrefix": "*",
                                    "destinationPortRange": "*",
                                    "destinationAddressPrefix": "*"
                                }
                            }
                        ]
                    }
                }
            }
        }
    }
}
}  

规则

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM