Skip to content

Commit 9acae3d

Browse files
committed
update
1 parent e311659 commit 9acae3d

File tree

1 file changed

+181
-19
lines changed

1 file changed

+181
-19
lines changed

articles/azure-resource-manager/resource-group-linked-templates.md

Lines changed: 181 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,55 @@ To nest a template, add a [deployments resource](/azure/templates/microsoft.reso
4444
}
4545
```
4646

47-
When using a nested template, you must specify whether template expressions are evaluated within the scope of the parent template or the nested template. You set the scope through the `expressionEvaluationOptions` property. By default, the `expressionEvaluationOptions` property is set to `outer`, which means it uses the parent template scope. Set the value to `inner` to scope expressions to the nested template.
47+
The following example deploys a storage account through a nested template.
4848

49-
The following template demonstrates how template expressions are resolved according to the scope. It contains a variable named `exampleVar` in the parent template and the nested template. When scope is set to `inner`, it returns `from nested template`. If you changed scope to `outer`, it would return `from parent template`.
49+
```json
50+
{
51+
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
52+
"contentVersion": "1.0.0.0",
53+
"parameters": {
54+
"storageAccountName": {
55+
"type": "string"
56+
}
57+
},
58+
"resources": [
59+
{
60+
"apiVersion": "2017-05-10",
61+
"name": "nestedTemplate1",
62+
"type": "Microsoft.Resources/deployments",
63+
"properties": {
64+
"mode": "Incremental",
65+
"template": {
66+
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
67+
"contentVersion": "1.0.0.0",
68+
"resources": [
69+
{
70+
"type": "Microsoft.Storage/storageAccounts",
71+
"apiVersion": "2019-04-01",
72+
"name": "[parameters('storageAccountName')]",
73+
"location": "West US",
74+
"kind": "StorageV2",
75+
"sku": {
76+
"name": "Standard_LRS"
77+
}
78+
}
79+
]
80+
}
81+
}
82+
}
83+
],
84+
"outputs": {
85+
}
86+
}
87+
```
88+
89+
## Scope for expressions in nested templates
90+
91+
When using a nested template, you must specify whether template expressions are evaluated within the scope of the parent template or the nested template. The scope determines how parameters, variables, and functions like [resourceGroup](resource-group-template-functions-resource.md#resourcegroup) and [subscription](resource-group-template-functions-resource.md#subscription) are resolved.
92+
93+
You set the scope through the `expressionEvaluationOptions` property. By default, the `expressionEvaluationOptions` property is set to `outer`, which means it uses the parent template scope. In the preceding example, the scope isn't set so the value of the `storageAccountName` parameter is retrieved from the parent template. Set the value to `inner` to scope expressions to the nested template.
94+
95+
The following template demonstrates how template expressions are resolved according to the scope. It contains a variable named `exampleVar` that is defined in both the parent template and the nested template. It returns the value of the variable.
5096

5197
```json
5298
{
@@ -95,15 +141,130 @@ The following template demonstrates how template expressions are resolved accord
95141
}
96142
```
97143

144+
The value of the variable changes based on the scope. The following table shows the results for both scopes.
145+
146+
| Scope | Output |
147+
| ----- | ------ |
148+
| inner | from nested template |
149+
| outer (or default) | from parent template |
150+
151+
The following example deploys a SQL server and retrieves a key vault secret to use for the password. The scope is set to `inner` because it dynamically creates the key vault ID and passes it as a parameter to the nested template.
152+
153+
```json
154+
{
155+
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
156+
"contentVersion": "1.0.0.0",
157+
"parameters": {
158+
"location": {
159+
"type": "string",
160+
"defaultValue": "[resourceGroup().location]",
161+
"metadata": {
162+
"description": "The location where the resources will be deployed."
163+
}
164+
},
165+
"vaultName": {
166+
"type": "string",
167+
"metadata": {
168+
"description": "The name of the keyvault that contains the secret."
169+
}
170+
},
171+
"secretName": {
172+
"type": "string",
173+
"metadata": {
174+
"description": "The name of the secret."
175+
}
176+
},
177+
"vaultResourceGroupName": {
178+
"type": "string",
179+
"metadata": {
180+
"description": "The name of the resource group that contains the keyvault."
181+
}
182+
},
183+
"vaultSubscription": {
184+
"type": "string",
185+
"defaultValue": "[subscription().subscriptionId]",
186+
"metadata": {
187+
"description": "The name of the subscription that contains the keyvault."
188+
}
189+
}
190+
},
191+
"resources": [
192+
{
193+
"apiVersion": "2018-05-01",
194+
"name": "dynamicSecret",
195+
"type": "Microsoft.Resources/deployments",
196+
"properties": {
197+
"mode": "Incremental",
198+
"expressionEvaluationOptions": {
199+
"scope": "inner"
200+
},
201+
"template": {
202+
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
203+
"contentVersion": "1.0.0.0",
204+
"parameters": {
205+
"adminLogin": {
206+
"type": "string"
207+
},
208+
"adminPassword": {
209+
"type": "securestring"
210+
},
211+
"location": {
212+
"type": "string"
213+
}
214+
},
215+
"variables": {
216+
"sqlServerName": "[concat('sql-', uniqueString(resourceGroup().id, 'sql'))]"
217+
},
218+
"resources": [
219+
{
220+
"name": "[variables('sqlServerName')]",
221+
"type": "Microsoft.Sql/servers",
222+
"apiVersion": "2018-06-01-preview",
223+
"location": "[parameters('location')]",
224+
"properties": {
225+
"administratorLogin": "[parameters('adminLogin')]",
226+
"administratorLoginPassword": "[parameters('adminPassword')]"
227+
}
228+
}
229+
],
230+
"outputs": {
231+
"sqlFQDN": {
232+
"type": "string",
233+
"value": "[reference(variables('sqlServerName')).fullyQualifiedDomainName]"
234+
}
235+
}
236+
},
237+
"parameters": {
238+
"location": {
239+
"value": "[parameters('location')]"
240+
},
241+
"adminLogin": {
242+
"value": "ghuser"
243+
},
244+
"adminPassword": {
245+
"reference": {
246+
"keyVault": {
247+
"id": "[resourceId(parameters('vaultSubscription'), parameters('vaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]"
248+
},
249+
"secretName": "[parameters('secretName')]"
250+
}
251+
}
252+
}
253+
}
254+
}
255+
],
256+
"outputs": {
257+
}
258+
}
259+
```
260+
98261
> [!NOTE]
99262
>
100263
> When scope is set to `outer`, you can't use the `reference` function in the outputs section of a nested template for a resource you have deployed in the nested template. To return the values for a deployed resource in a nested template, either use inner scope or convert your nested template to a linked template.
101264
102-
The nested template requires the [same properties](resource-group-authoring-templates.md) as a standard template.
103-
104265
## Linked template
105266

106-
To link a template, add a [deployments resource](/azure/templates/microsoft.resources/deployments) to your main template. In the **templateLink** property, specify the URI of the template to include.
267+
To link a template, add a [deployments resource](/azure/templates/microsoft.resources/deployments) to your main template. In the **templateLink** property, specify the URI of the template to include. The following example links to a template that deploys a new storage account.
107268

108269
```json
109270
{
@@ -114,12 +275,13 @@ To link a template, add a [deployments resource](/azure/templates/microsoft.reso
114275
"resources": [
115276
{
116277
"apiVersion": "2017-05-10",
117-
"name": "nestedTemplate1",
278+
"name": "linkedTemplate",
118279
"type": "Microsoft.Resources/deployments",
119280
"properties": {
120281
"mode": "Incremental",
121282
"templateLink": {
122-
"uri": <uri-for-linked-template>
283+
"uri":"https://mystorageaccount.blob.core.windows.net/AzureTemplates/newStorageAccount.json",
284+
"contentVersion":"1.0.0.0"
123285
}
124286
}
125287
}
@@ -131,11 +293,11 @@ To link a template, add a [deployments resource](/azure/templates/microsoft.reso
131293

132294
You can't specify a local file or a file that is only available on your local network. You can only provide a URI value that includes either **http** or **https**. Resource Manager must be able to access the template. One option is to place your linked template in a storage account, and use the URI for that item.
133295

134-
You can provide the parameters for your external template either in an external file or inline.
296+
You don't have to provide the `contentVersion` property for the template or parameters. If you don't provide a content version value, the current version of the template is deployed. If you provide a value for content version, it must match the version in the linked template; otherwise, the deployment fails with an error.
135297

136-
### External parameters
298+
### Parameters for linked template
137299

138-
When providing an external parameter file, use the **parametersLink** property:
300+
You can provide the parameters for your linked template either in an external file or inline. When providing an external parameter file, use the **parametersLink** property:
139301

140302
```json
141303
"resources": [
@@ -158,13 +320,7 @@ When providing an external parameter file, use the **parametersLink** property:
158320
]
159321
```
160322

161-
You don't have to provide the `contentVersion` property for the template or parameters. If you don't provide a content version value, the current version of the template is deployed. If you provide a value for content version, it must match the version in the linked template; otherwise, the deployment fails with an error.
162-
163-
### Inline parameters
164-
165-
Or, you can provide the parameter inline. You can't use both inline parameters and a link to a parameter file. The deployment fails with an error when both `parametersLink` and `parameters` are specified.
166-
167-
To pass a value from the main template to the linked template, use the **parameters** property.
323+
To pass parameter values inline, use the **parameters** property.
168324

169325
```json
170326
"resources": [
@@ -186,9 +342,11 @@ To pass a value from the main template to the linked template, use the **paramet
186342
]
187343
```
188344

345+
You can't use both inline parameters and a link to a parameter file. The deployment fails with an error when both `parametersLink` and `parameters` are specified.
346+
189347
## Using copy
190348

191-
To create multiple instances of a resource with a nested template, add the copy element at the level of the **Microsoft.Resources/deployments** resource.
349+
To create multiple instances of a resource with a nested template, add the copy element at the level of the **Microsoft.Resources/deployments** resource. Or, if the scope is inner, you can add the copy within the nested template.
192350

193351
The following example template shows how to use copy with a nested template.
194352

@@ -205,6 +363,9 @@ The following example template shows how to use copy with a nested template.
205363
},
206364
"properties": {
207365
"mode": "Incremental",
366+
"expressionEvaluationOptions": {
367+
"scope": "inner"
368+
},
208369
"template": {
209370
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
210371
"contentVersion": "1.0.0.0",
@@ -218,7 +379,8 @@ The following example template shows how to use copy with a nested template.
218379
"sku": {
219380
"name": "Standard_LRS"
220381
}
221-
// no, copy doesn't work here
382+
// Copy works here when scope is inner
383+
// But, when scope is default or outer, you get an error
222384
//"copy":{
223385
// "name": "storagecopy",
224386
// "count": 2

0 commit comments

Comments
 (0)