Azure / arm-ttk

Azure Resource Manager Template Toolkit
https://aka.ms/arm-ttk
MIT License
441 stars 189 forks source link

Location Should Not Be Hardcoded test #310

Open kkazala opened 3 years ago

kkazala commented 3 years ago

"Location Should Not Be Hardcoded" test fails for some resources, when the parameter is using default value set to [resourceGroup().location]

E.g.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        [...]
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "Location for the resources."
            }
        }
    },
    "resources": [
        //ServiceBus with Queue 
        {
            "apiVersion": "2018-01-01-preview",
            "name": "[parameters('serviceBusNamespaceName')]",
            "type": "Microsoft.ServiceBus/namespaces",
            "location": "[parameters('location')]",
            "kind": "Messaging",
            "sku": {
                "name": "Basic"
            },
[...]
}

passes the validation , but

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        [...]
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "Location for the resources."
            }
        }
    },
    "resources": [
        {
            "type": "Microsoft.Logic/workflows",
            "apiVersion": "2019-05-01",
            "name": "[parameters('logicAppName')]",
            "location": "[parameters('location')]",
             [...]
}

fails with [-] Location Should Not Be Hardcoded (40 ms) azuredeploy.json must use the location parameter, not resourceGroup().location (except when used as a default value in the main template) The same error is thrown for "type": "Microsoft.Web/connections"

All ARM templates are main templates named azuredeploy.json

bmoore-msft commented 3 years ago

@kkazala can you share a full template for the repro?

bmoore-msft commented 3 years ago

@kkazala - just checking to see if you have a repro handy?

amorabito2w commented 3 years ago

I'm having a similar issue, only my error is: "The location parameter of nested templates must not have a defaultValue property. It is "[resourceGroup().location]"

The template deploys fine. Hopefully this will help shed some light on the issue :)

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "0.1.0",
    "parameters": {
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]",
            "metadata": {
                "description": "The location of the Synapse Analytics workspace and Stream Analytics job."
            }
        },
        "synapseAnalyticsWorkspaceName": {
            "type": "string",
            "metadata": {
                "description": "The name of the Synapse Analytics workspace to be used for batch processing and analytics data store."
            }
        },
        "dataLakeStorageAccountName": {
            "type": "string",
            "metadata": {
                "description": "The name of the Data Lake Stroage account."
            }
        },
        "dataLakeStorageFilesystemName": {
            "type": "string",
            "defaultValue": "synapse-analytics",
            "minLength": 3,
            "maxLength": 63,
            "metadata": {
                "description": "The name of the file system to be used with the Azure Data Lake Storage Gen2 account. This name may only contain lowercase letters, numbers, and hyphens, and must begin with a letter or a number. Each hyphen must be preceded and followed by a non-hyphen character. The name must also be between 3 and 63 characters long."
            }
        },
        "sqlAdministratorLogin": {
            "type": "string",
            "metadata": {
                "description": "The name of the SQL administrator account."
            }
        },
        "sqlAdministratorLoginPassword": {
            "type": "securestring",
            "metadata": {
                "description": "The password for the SQL administrator account."
            }
        },
        "synapseAnalyticsTagValues": {
            "type": "object",
            "defaultValue": {},
            "metadata": {
                "description": "Tag values in hash table format."
            }
        },
        "streamAnalyticsJobName": {
            "type": "string",
            "metadata": {
                "description": "The name of the Stream Analytics job."
            }
        },
        "streamAnalyticsJobTagValues": {
            "type": "object",
            "defaultValue": {},
            "metadata": {
                "description": "Tag values in hash table format."
            }
        }
    },
    "variables": {
        "synapseAnalyticsWorkspaceName": "[concat('asynaws-', parameters('synapseAnalyticsWorkspaceName'))]",
        "managedResourceGroupName": "[concat('asynaws-', parameters('synapseAnalyticsWorkspaceName'), '-managedrg')]",
        "defaultDataLakeStorageAccountUrl": "[concat('https://', parameters('dataLakeStorageAccountName'), '.dfs.core.windows.net')]",
        "streamAnalyticsJobName": "[concat('astrajob-', parameters('streamAnalyticsJobName'))]",
    },
    "resources": [
        {
            "type": "Microsoft.Synapse/workspaces",
            "apiVersion": "2019-06-01-preview",
            "name": "[variables('synapseAnalyticsWorkspaceName')]",
            "location": "[parameters('location')]",
            "tags": "[parameters('synapseAnalyticsTagValues')]",
            "identity": {
                "type": "SystemAssigned"
            },
            "properties": {
                "defaultDataLakeStorage": {
                    "accountUrl": "[variables('defaultDataLakeStorageAccountUrl')]",
                    "filesystem": "[parameters('dataLakeStorageFilesystemName')]"
                },
                "sqlAdministratorLogin": "[parameters('sqlAdministratorLogin')]",
                "sqlAdministratorLoginPassword": "[parameters('sqlAdministratorLoginPassword')]",
                "managedResourceGroupName": "[variables('managedResourceGroupName')]"
            }
        },
        {
            "type": "Microsoft.Storage/storageAccounts/blobServices/containers",
            "name": "[concat(parameters('dataLakeStorageAccountName'), '/default/', parameters('dataLakeStorageFilesystemName'))]",
            "apiVersion": "2018-02-01",
            "properties": {
                "publicAccess": "None"
            }
        },
        {
            "type": "Microsoft.StreamAnalytics/streamingjobs",
            "apiVersion": "2017-04-01-preview",
            "name": "[variables('streamAnalyticsJobName')]",
            "location": "[parameters('location')]",
            "tags": "[parameters('streamAnalyticsJobTagValues')]",
            "properties": {
                "sku": {
                    "name": "Standard"
                },
                "eventsOutOfOrderMaxDelayInSeconds": 0,
                "eventsLateArrivalMaxDelayInSeconds": 5,
                "compatibilityLevel": "1.2",
                "contentStoragePolicy": "SystemAccount",
                "jobType": "Cloud"
            }
        }
    ],
    "outputs": {}
}
bmoore-msft commented 3 years ago

The defaultValue in a nested template is intentional for the location property - this is to ensure the location is passed through to the nested deployment (as the location used by the parent may be different than the location used by the nested deployment and cause failures).