Skip to content

Commit 97d7799

Browse files
authored
Merge pull request #184402 from StephenWeatherford/sw/location-linter-rules
new location-related linter rules
2 parents 23e0baa + 803f356 commit 97d7799

File tree

4 files changed

+242
-0
lines changed

4 files changed

+242
-0
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
---
2+
title: Linter rule - use explicit values for module location parameters
3+
description: Linter rule - use explicit values for module location parameters
4+
ms.topic: conceptual
5+
ms.date: 1/6/2022
6+
---
7+
8+
# Linter rule - use explicit values for module location parameters
9+
10+
This rule finds module parameters that are used for resource locations and may inadvertently default to an unexpected value.
11+
12+
## Linter rule code
13+
14+
Use the following value in the [Bicep configuration file](bicep-config-linter.md) to customize rule settings:
15+
16+
`explicit-values-for-loc-params`
17+
18+
## Solution
19+
20+
When you consume a module, any location-related parameters that have a default value should be assigned an explicit value. Location-related parameters include parameters that have a default value referencing `resourceGroup().location` or `deployment().location` and also any parameter that is referenced from a resource's location property.
21+
22+
A parameter that defaults to a resource group's or deployment's location is convenient when a bicep file is used as a main deployment template. However, when such a default value is used in a module, it may cause unexpected behavior if the main template's resources aren't located in the same region as the resource group.
23+
24+
### Examples
25+
26+
The following example fails this test. Module `m1`'s parameter `location` isn't assigned an explicit value, so it will default to `resourceGroup().location`, as specified in *module1.bicep*. But using the resource group location may not be the intended behavior, since other resources in *main.bicep* might be created in a different location than the resource group's location.
27+
28+
*main.bicep*:
29+
```bicep
30+
param location string = 'eastus'
31+
32+
module m1 'module1.bicep' = {
33+
name: 'm1'
34+
}
35+
36+
resource storageaccount 'Microsoft.Storage/storageAccounts@2021-02-01' = {
37+
name: 'storageaccount'
38+
location: location
39+
kind: 'StorageV2'
40+
sku: {
41+
name: 'Standard_LRS'
42+
}
43+
}
44+
```
45+
46+
*module1.bicep*:
47+
```bicep
48+
param location string = resourceGroup().location
49+
50+
resource stg 'Microsoft.Storage/storageAccounts@2021-02-01' = {
51+
name: 'stg'
52+
location: location
53+
kind: 'StorageV2'
54+
sku: {
55+
name: 'Premium_LRS'
56+
}
57+
}
58+
```
59+
60+
You can fix the failure by explicitly passing in a value for the module's `location` property:
61+
62+
*main.bicep*:
63+
```bicep
64+
param location string = 'eastus'
65+
66+
module m1 'module1.bicep' = {
67+
name: 'm1'
68+
params: {
69+
location: location // An explicit value will override the default value specified in module1.bicep
70+
}
71+
}
72+
73+
resource storageaccount 'Microsoft.Storage/storageAccounts@2021-02-01' = {
74+
name: 'storageaccount'
75+
location: location
76+
kind: 'StorageV2'
77+
sku: {
78+
name: 'Standard_LRS'
79+
}
80+
}
81+
```
82+
83+
## Next steps
84+
85+
For more information about the linter, see [Use Bicep linter](./linter.md).
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
---
2+
title: Linter rule - no hard-coded locations
3+
description: Linter rule - no hard-coded locations
4+
ms.topic: conceptual
5+
ms.date: 1/6/2022
6+
---
7+
8+
# Linter rule - no hard-coded locations
9+
10+
This rule finds uses of Azure location values that aren't parameterized.
11+
12+
## Linter rule code
13+
14+
Use the following value in the [Bicep configuration file](bicep-config-linter.md) to customize rule settings:
15+
16+
`no-hardcoded-location`
17+
18+
## Solution
19+
20+
Template users may have limited access to regions where they can create resources. A hard-coded resource location might block users from creating a resource, thus preventing them from using the template. By providing a location parameter that defaults to the resource group location, users can use the default value when convenient but also specify a different location.
21+
22+
Rather than using a hard-coded string or variable value, use a parameter, the string 'global', or an expression (but not `resourceGroup().location` or `deployment().location`, see [no-loc-expr-outside-params](./linter-rule-no-loc-expr-outside-params.md)). Best practice suggests that to set your resources' locations, your template should have a string parameter named `location`. This parameter may default to the resource group or deployment location (`resourceGroup().location` or `deployment().location`).
23+
24+
The following example fails this test because the resource's `location` property uses a string literal:
25+
26+
```bicep
27+
resource stg 'Microsoft.Storage/storageAccounts@2021-02-01' = {
28+
location: 'westus'
29+
}
30+
```
31+
You can fix it by creating a new `location` string parameter (which may optionally have a default value - resourceGroup().location is frequently used as a default):
32+
33+
```bicep
34+
param location string = resourceGroup().location
35+
resource stg 'Microsoft.Storage/storageAccounts@2021-02-01' = {
36+
location: location
37+
}
38+
```
39+
40+
The following example fails this test because the resource's `location` property uses a variable with a string literal.
41+
42+
```bicep
43+
var location = 'westus'
44+
resource stg 'Microsoft.Storage/storageAccounts@2021-02-01' = {
45+
location: location
46+
}
47+
```
48+
49+
You can fix it by turning the variable into a parameter:
50+
51+
```bicep
52+
param location string = 'westus'
53+
resource stg 'Microsoft.Storage/storageAccounts@2021-02-01' = {
54+
location: location
55+
}
56+
```
57+
58+
The following example fails this test because a string literal is being passed in to a module parameter that is in turn used for a resource's `location` property:
59+
60+
```bicep
61+
module m1 'module1.bicep' = {
62+
name: 'module1'
63+
params: {
64+
location: 'westus'
65+
}
66+
}
67+
```
68+
where module1.bicep is:
69+
```bicep
70+
param location string
71+
72+
resource storageaccount 'Microsoft.Storage/storageAccounts@2021-02-01' = {
73+
name: 'storageaccount'
74+
location: location
75+
kind: 'StorageV2'
76+
sku: {
77+
name: 'Premium_LRS'
78+
}
79+
}
80+
```
81+
82+
You can fix the failure by creating a new parameter for the value:
83+
```bicep
84+
param location string // optionally with a default value
85+
module m1 'module1.bicep' = {
86+
name: 'module1'
87+
params: {
88+
location: location
89+
}
90+
}
91+
```
92+
93+
## Next steps
94+
95+
For more information about the linter, see [Use Bicep linter](./linter.md).
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
title: Linter rule - no location expressions outside of parameter default values
3+
description: Linter rule - no location expressions outside of parameter default values
4+
ms.topic: conceptual
5+
ms.date: 1/6/2022
6+
---
7+
8+
# Linter rule - no location expressions outside of parameter default values
9+
10+
This rule finds `resourceGroup().location` or `deployment().location` used outside of a parameter default value.
11+
12+
## Linter rule code
13+
14+
Use the following value in the [Bicep configuration file](bicep-config-linter.md) to customize rule settings:
15+
16+
`no-loc-expr-outside-params`
17+
18+
## Solution
19+
20+
`resourceGroup().location` and `deployment().location` should only be used as the default value of a parameter.
21+
22+
Template users may have limited access to regions where they can create resources. The expressions `resourceGroup().location` or `deployment().location` could block users if the resource group or deployment was created in a region the user can't access, thus preventing them from using the template.
23+
24+
Best practice suggests that to set your resources' locations, your template should have a string parameter named `location`. If you default the `location` parameter to `resourceGroup().location` or `deployment().location` instead of using these functions elsewhere in the template, users of the template can use the default value when convenient but also specify a different location when needed.
25+
26+
```bicep
27+
resource storageaccount 'Microsoft.Storage/storageAccounts@2021-02-01' = {
28+
location: resourceGroup().location
29+
}
30+
```
31+
32+
You can fix the failure by creating a `location` property that defaults to `resourceGroup().location` and use this new parameter instead:
33+
34+
```bicep
35+
param location string = resourceGroup().location
36+
37+
resource storageaccount 'Microsoft.Storage/storageAccounts@2021-02-01' = {
38+
location: location
39+
}
40+
```
41+
42+
The following example fails this test because `location` is using `resourceGroup().location` but isn't a parameter:
43+
44+
```bicep
45+
var location = resourceGroup().location
46+
```
47+
48+
You can fix the failure by turning the variable into a parameter:
49+
50+
```bicep
51+
param location string = resourceGroup().location
52+
```
53+
54+
## Next steps
55+
56+
For more information about the linter, see [Use Bicep linter](./linter.md).

articles/azure-resource-manager/bicep/toc.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,10 @@
182182
href: linter-rule-max-variables.md
183183
- name: No hardcoded environment URLs
184184
href: linter-rule-no-hardcoded-environment-urls.md
185+
- name: No hard-coded locations
186+
href: linter-rule-no-hardcoded-location.md
187+
- name: No location expressions outside of parameter default values
188+
href: linter-rule-no-loc-expr-outside-params.md
185189
- name: No unnecessary dependsOn entries
186190
href: linter-rule-no-unnecessary-dependson.md
187191
- name: No unused parameters
@@ -196,6 +200,8 @@
196200
href: linter-rule-secure-parameter-default.md
197201
- name: Simplify interpolation
198202
href: linter-rule-simplify-interpolation.md
203+
- name: Use explicit values for module location parameters
204+
href: linter-rule-explicit-values-for-loc-params.md
199205
- name: Use protectedSettings for commandToExecute secrets
200206
href: linter-rule-use-protectedsettings-for-commandtoexecute-secrets.md
201207
- name: Use stable VM image

0 commit comments

Comments
 (0)