Skip to content

Commit d91d65d

Browse files
committed
Add details to no deployments resources linter rule
1 parent db3cffd commit d91d65d

File tree

1 file changed

+149
-12
lines changed

1 file changed

+149
-12
lines changed

articles/azure-resource-manager/bicep/linter-rule-no-deployments-resources.md

Lines changed: 149 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Linter rule - no deployments resources
33
description: Linter rule - no deployments resources
44
ms.topic: conceptual
55
ms.custom: devx-track-bicep
6-
ms.date: 10/12/2023
6+
ms.date: 02/12/2024
77
---
88

99
# Linter rule - no deployments resources
@@ -18,24 +18,161 @@ Use the following value in the [Bicep configuration file](bicep-config-linter.md
1818

1919
## Solution
2020

21-
The following example fails this test because the template contains a `Microsoft.Resources/deployments` resource on the root level.
21+
In ARM templates, you have the capability to reuse or modularize a template through nesting or linking templates using the `Microsoft.Resources/deployments` resource. Below is an illustration of a nested template:
22+
23+
```json
24+
{
25+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
26+
"contentVersion": "1.0.0.0",
27+
"parameters": {
28+
"storageAccountName": {
29+
"type": "string",
30+
"defaultValue": "[format('{0}{1}', 'store', uniqueString(resourceGroup().id))]"
31+
},
32+
"location": {
33+
"type": "string",
34+
"defaultValue": "[resourceGroup().location]"
35+
}
36+
},
37+
"resources": [
38+
{
39+
"type": "Microsoft.Resources/deployments",
40+
"apiVersion": "2022-09-01",
41+
"name": "nestedTemplate1",
42+
"properties": {
43+
"mode": "Incremental",
44+
"template": {
45+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
46+
"contentVersion": "1.0.0.0",
47+
"resources": [
48+
{
49+
"type": "Microsoft.Storage/storageAccounts",
50+
"apiVersion": "2023-01-01",
51+
"name": "[parameters('storageAccountName')]",
52+
"location": "[parameters('location')]",
53+
"sku": {
54+
"name": "Standard_LRS"
55+
},
56+
"kind": "StorageV2"
57+
}
58+
]
59+
}
60+
}
61+
}
62+
]
63+
}
64+
```
65+
66+
In Bicep, you can still use the `Microsoft.Resources/deployments` resource for nesting ARM templates or linking external ARM templates. But, it's not a great idea because it can lead to unsafe and tricky behaviors due to how it's evaluated multiple times. Also, there's hardly any validation and self completion from the Visual Studio Code editor, making it tough to work with. The following Bicep file fails this test because the template contains `Microsoft.Resources/deployments` resource on the root level.
2267

2368
```bicep
24-
param name string
25-
param specId string
26-
resource foo 'Microsoft.Resources/deployments@2023-07-01' = {
27-
name: name
28-
properties: {
69+
param storageAccountName string = 'store${uniqueString(resourceGroup().id)}'
70+
param location string = resourceGroup().location
71+
72+
resource nestedTemplate1 'Microsoft.Resources/deployments@2023-07-01' = {
73+
name: 'nestedTemplate1'
74+
properties:{
2975
mode: 'Incremental'
30-
templateLink: {
31-
uri: specId
32-
}
33-
parameters: {}
76+
template: {
77+
'$schema': 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#'
78+
contentVersion: '1.0.0.0'
79+
resources: [
80+
{
81+
type: 'Microsoft.Storage/storageAccounts'
82+
apiVersion: '2023-01-01'
83+
name: storageAccountName
84+
location: location
85+
sku: {
86+
name: 'Standard_LRS'
87+
}
88+
kind: 'StorageV2'
89+
}
90+
]
91+
}
92+
}
93+
}
94+
```
95+
96+
To fix the issue, you can use the Bicep CLI [decompile](./bicep-cli.md#decompile) command. For example, the preceding ARM template can be decomplied into the following Bicep files:
97+
98+
main.bicep:
99+
100+
```bicep
101+
param storageAccountName string = 'store${uniqueString(resourceGroup().id)}'
102+
param location string = resourceGroup().location
103+
104+
module nestedTemplate1 './nested_nestedTemplate1.bicep' = {
105+
name: 'nestedTemplate1'
106+
params: {
107+
storageAccountName: storageAccountName
108+
location: location
34109
}
35110
}
36111
```
37112

38-
It should be declared as a [Bicep module](./modules.md).
113+
nested_nestedTemplate1.bicep:
114+
115+
```bicep
116+
param storageAccountName string
117+
param location string
118+
119+
resource storageAccount 'Microsoft.Storage/storageAccounts@2023-01-01' = {
120+
name: storageAccountName
121+
location: location
122+
sku: {
123+
name: 'Standard_LRS'
124+
}
125+
kind: 'StorageV2'
126+
}
127+
```
128+
129+
Additionally, you can also refence the nested json template using the [module](./modules.md) statement.
130+
131+
main.bicep:
132+
133+
```bicep
134+
param storageAccountName string = 'store${uniqueString(resourceGroup().id)}'
135+
param location string = resourceGroup().location
136+
137+
module nestedTemplate1 './createStorage.json' = {
138+
name: 'nestedTemplate1'
139+
params: {
140+
storageAccountName: storageAccountName
141+
location: location
142+
}
143+
}
144+
```bicep
145+
146+
createStorage.json
147+
148+
```json
149+
{
150+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
151+
"contentVersion": "1.0.0.0",
152+
"parameters": {
153+
"storageAccountName": {
154+
"type": "string",
155+
"defaultValue": "[format('{0}{1}', 'store', uniqueString(resourceGroup().id))]"
156+
},
157+
"location": {
158+
"type": "string",
159+
"defaultValue": "[resourceGroup().location]"
160+
}
161+
},
162+
"resources": [
163+
{
164+
"type": "Microsoft.Storage/storageAccounts",
165+
"apiVersion": "2023-01-01",
166+
"name": "[parameters('storageAccountName')]",
167+
"location": "[parameters('location')]",
168+
"sku": {
169+
"name": "Standard_LRS"
170+
},
171+
"kind": "StorageV2"
172+
}
173+
]
174+
}
175+
```
39176

40177
## Next steps
41178

0 commit comments

Comments
 (0)