1
votes

I'm working on an ARM template and need to perform conditional deployment. For instance, I've got two network security groups defined in a variable 'subnets'.

"variables": {
    "subnets": [
        {
            "subnetname": "AzureBastionSubnet",
            "nsgname": "nsg_bastion1"
        },
        {
            "subnetname": "client-subnet",
            "nsgname": "nsg_client1"
        }
    ]
}

The network security group 'nsg_bastion1' needs special treatment with predefined rules since it is a network security group for an Azure Bastion subnet. 'nsg_client1' will get some custom rules assigned, which don't matter at this point.

In order to differentiate between non-Bastion and Bastion-network security groups, I've created two conditional resource blocks:

"resources": [
// NSG (non-Bastion)
{
    "condition": "[not(equals(variables('subnets')[copyIndex()].name, 'AzureBastionSubnet'))]",
    "name": "[variables('subnets')[copyIndex()].nsg]",
    "type": "Microsoft.Network/networkSecurityGroups",
    "apiVersion": "2019-11-01",
    "location": "[parameters('location')]",
    "properties": {},
    "copy": {
        "name": "nsg-c",
        "count": "[length(variables('subnets'))]"
    }
},
// NSG (Bastion)
{
    "condition": "[equals(variables('subnets')[copyIndex()].name, 'AzureBastionSubnet')]",
    "name": "[variables('subnets')[copyIndex()].nsg]",
    "type": "Microsoft.Network/networkSecurityGroups",
    "apiVersion": "2019-11-01",
    "location": "[parameters('location')]",
    "properties": {},
    "resources": [
        // Bastion Security Rules .....
    ],
    "copy": {
        "name": "nsg-bastion-c",
        "count": "[length(variables('subnets'))]"
    }
},]

The condition property checks whether the subnet is called 'AzureBastionSubnet' or not. I've verified that this works for both resource blocks alone, but it doesn't when they're included both in the code. It always throws the following error message:

    Code=InvalidTemplate; Message=Deployment template validation failed:
'The resource 'Microsoft.Network/networkSecurityGroups/AzureBastionSubnet' at line '' and column '' is defined multiple times in a template.

I'd appreciate any help, thanks in advance!

1
I would suggest to set AzureBastion NSG as a different parameter instead of including it in the same array for normal NSGs. I wonder how copyIndex() works inside a condition.stackoverflowusrone
How are you deploying the template? More specifically do you know what apiVersion is in the PUT on the deployment? (this is meant to be fixed)bmoore-msft
nm - see answer below...bmoore-msft

1 Answers

0
votes

Ok, I thought we had fixed this but not yet...

Even though your conditions are mutually exclusive, you can't have 2 resources with the same resourceId in the same template.

I'm guessing the difference between the two is in the securityRules? If so, simplest option may be to define 2 separate vars and then use an if() statement to swap between them based on your condition.

Failing that if you want to expand on the template can see if there is a better option...