Azure ARM Templates – Conditionally setting resource properties

Using Azure Resource Manager(ARM) templates, you can deploy resources based on some condition. You can use the Condition element or the If function to achieve this.

When you want to conditionally deploy a top-level resource based on the value of a parameter, the condition element can be used. Conditions cannot be used with child resources. When you want to conditionally set a property of a resource, the If function comes in handy.

Consider this scenario. You may prefer to deploy resources in different tiers in different environments to reduce cost. Some features are only available in higher tiers. In order to “turn off” a certain feature that is not supported in the chosen tier, you can set the property to null based on a condition.

Let me give you an example. You can provision Azure API Management in more than one region when you’re in the Premium tier and Premium tier is expensive. When you’re deploying the resource to a dev environment, for example, you will most likely deploy it in the Developer tier. You can pass the sku as a parameter to the template.

"apimSku":{
    "type": "string",
    "allowedValues": [
        "Developer",
        "Standard",
        "Premium"
    ],
    "defaultValue": "Developer",
    "metadata": {
        "description": "The pricing tier of this API Management service"
    }
}

The additionalLocations property needs to be set based on the tier you are passing in as the parameter. You can declare a variable that will hold the additional locations and it needs to be an array of objects. The below snippet shows a variable that defines a single additional location in a premium tier and the virtual network it will be deployed to.

"variables": {
    "additionalLocation": [{
                    "location": "Australia Southeast",
                    "sku": {
                        "name": "Premium",
                        "capacity": 1
                    },
                    "virtualNetworkConfiguration": {
                        "subnetResourceId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnet2'), parameters('subnet2'))]"
                    }
                }]
}

To keep things simple, I’m assuming the virtual networks have already been provisioned. If you want to deploy the virtual networks along with the API Management service, you can use the copy loop to create the virtual networks. The copy loop name will also be added to the dependsOn array of the API Management resource.

Based on the tier, you can either set additionalLocations to the variable defined above or set it to null by using the if function. The first parameter is the condition to be checked. The function returns the second parameter if the condition evaluates to true else returns the third parameter.

"resources": [
{
    "type": "Microsoft.ApiManagement/service",
    "sku": {
        "name": "[parameters('apimSku')]",
        "capacity": 1
    },
    "name": "[parameters('apimName')]",
    "apiVersion": "2017-03-01",
    "location": "Australia East",
    "tags": {},
    "properties": {
        "publisherEmail": "INSERT YOUR EMAIL HERE",
        "publisherName": "RJ",
        "notificationSenderEmail": "apimgmt-noreply@mail.windowsazure.com",
        "hostnameConfigurations": [],
        "virtualNetworkType": "Internal",
        "virtualNetworkConfiguration": {
            "subnetResourceId": "[resourceId('Microsoft.Network/virtualNetworks/subnets', parameters('vnet1'), parameters('subnet1'))]"
        },
        "additionalLocations": "[if(equals(parameters('apimSku'), 'Premium'), variables('additionalLocation'), json('null'))]",
    },
    "dependsOn": []
}

Now, if you pass Premium as the sku, API Management service will be deployed to Australia East and Australia Southeast. If you pass Developer as the sku, then the service will be deployed only to Australia East in the above example.

Leave a comment