Skip to content

Use a location parameter for regional resources#

Operational Excellence · All resources · Rule · 2021_03 · Awareness

Resource locations should be an expression or global.

Description#

The location property is a required property for most Azure resources. For non-regional resources such as Front Door and DNS Zones specify a literal location global instead.

The resource location determines where the resource configuration is stored and managed from. Commonly this will also indicate which region your data is stored in.

When defining resources in Bicep or ARM templates, avoid hardcoding the location value, even when you know the location. The location value should be a parameter what can be easily set or overridden when deploying the template. This makes the template more flexible and reusable across different environments as requirements change.

Reusable templates and modules may include different resources that are deployed to different locations. Define a location parameter value for resources that are likely to be in the same location. This approach minimizes the number of times users are asked to provide location information. For resources that aren't available in all locations, use a separate parameter.

Use Azure Policy to enforce the location of resources in your environment at runtime.

Recommendation#

Consider updating the resource location property to use a parameter to make templates and modules more flexible and reusable.

Examples#

Configure with Azure template#

To deploy resources that pass this rule:

  • Set the location property to a parameter or global.

For example:

Azure Template snippet
{
  "type": "Microsoft.Storage/storageAccounts",
  "apiVersion": "2023-01-01",
  "name": "[parameters('name')]",
  "location": "[parameters('location')]",
  "sku": {
    "name": "Standard_GRS"
  },
  "kind": "StorageV2",
  "properties": {
    "allowBlobPublicAccess": false,
    "supportsHttpsTrafficOnly": true,
    "minimumTlsVersion": "TLS1_2",
    "accessTier": "Hot",
    "allowSharedKeyAccess": false,
    "networkAcls": {
      "defaultAction": "Deny"
    }
  }
}

To define a location parameter:

  • Under the parameters template property define a string sub-property.

For example:

Azure Template snippet
{
  "parameters": {
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]",
      "metadata": {
        "description": "The location resources will be deployed."
      }
    }
  }
}

Configure with Bicep#

To deploy resources that pass this rule:

  • Set the location property to a parameter or global.

For example:

Azure Bicep snippet
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
  name: name
  location: location
  sku: {
    name: 'Standard_GRS'
  }
  kind: 'StorageV2'
  properties: {
    allowBlobPublicAccess: false
    supportsHttpsTrafficOnly: true
    minimumTlsVersion: 'TLS1_2'
    accessTier: 'Hot'
    allowSharedKeyAccess: false
    networkAcls: {
      defaultAction: 'Deny'
    }
  }
}

To define a location parameter:

  • Use the param keyword.

For example:

Azure Bicep snippet
@description('The location resources will be deployed.')
param location string = resourceGroup().location

Notes#

By default, the Bicep linter rule no-hardcoded-location will raise a warning if a resource location is hardcoded.

Comments