1
votes

I have an ARM template that is used to create resources in the location of a given Resource Group. Here is how I can deploy a SignalR service:

    {
        "apiVersion": "2018-10-01",
        "name": "[variables('signalRName')]",
        "type": "Microsoft.SignalRService/signalR",
        "location": "[resourceGroup().location]",
        "tags": {},
        "sku": {
            "name": "Free_F1",
            "tier": "Free"
        },
        "properties": { }
   }

Being in Canada, I have access to two locations: Canada East and Canada Central. However SignalR that is not available in Canada Central yet but it is in Canada East:

ew-AzResourceGroupDeployment: 11:40:32 AM - Error: Code=LocationNotAvailableForResourceType; Message=The provided location 'canadacentral' is not available for resource type 'Microsoft.SignalRService/SignalR'. List of available regions for the resource type is 'eastus,westus,southeastasia,westeurope,westus2,eastus2,northeurope,australiaeast,canadaeast,centralus,japaneast,uksouth,southcentralus,brazilsouth,francecentral,koreacentral'.

Question

What can I do to deploy the resource unavailable in the primary location into some secondary / fallback location?

2

2 Answers

2
votes

I have found a way to achieve it at the expense of few tweaks. First, I have to specify myself a secondary location parameter in my parameters file.

For instance, in the following parameters file, I specified Canada Central as a primary location and Canada East as a secondary location:

    {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "primaryLocation": {
                "value": "Canada Central"
            },
            "secondaryLocation": {
                "value": "Canada East"
            }
            ...
        }
    }

This parameter is defined in my deploy template file:

    {
        "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
        "contentVersion": "1.0.0.0",
        "parameters": {
            "primaryLocation": {
                "type": "string",
                "minLength": 3,
                "maxLength": 32
            }
            "secondaryLocation": {
                "type": "string",
                "minLength": 3,
                "maxLength": 32
            }
        }
        ... }

Then I found out about the providers statement. This statement returns the list of locations available of a given resource type.

So I updated the location property to look for the resource group's location in the list of locations available for SignalR. If it is contained in the list, then I use resource group's location. Otherwise, I use the secondary location provided.

    {
        "apiVersion": "2018-10-01",
        "name": "[variables('signalRName')]",
        "type": "Microsoft.SignalRService/signalR",
        "location": "[if(contains(providers('Microsoft.SignalRService', 'signalR').locations, parameters('primaryLocation')), parameters('primaryLocation'), parameters('secondaryLocation'))]",
        "tags": {},
        "sku": {
            "name": "Free_F1",
            "tier": "Free"
        },
        "properties": { }
    }

Note

I can't use resourceGroup().location because it does not return the location in the same format as providers('Microsoft.SignalRService', 'signalR').locations. The first one will return something like canadaeast whereas the second returns Canada East.

0
votes

You cannot do that, you have to either know this beforehand or just handle the failure outside of the arm template and redeploy into another region. most of the services offer an api endpoint to figure out which locations are supported