I need you help with an ARM template issue I'm facing. Here's a brief summary: I am working on creating a template for deploying a resource group and several resources related to Azure Machine Learning. Since I need to deploy multiple instances within the same subscription, I'm using a subscription-level template.
I want to format the names of various components consistently. For example, given a workspace name like my_project-Name, I need to transform it into (some users do not follow the usage of '-' or '_'):
The reason for these transformations is that groups are usually named as gr-name, workspaces as mlw-project-XX, storage accounts as stmlwprojectXXX, and other services as mlw-project-XX--AB.
Here's the template I’m using:
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"grPrefix":{
"type": "string",
"defaultValue":"gr-mlw-"
},
"rgLocation": {
"type": "string",
"allowedValues":[
"eastus2",
"swedencentral",
"taiwannorth"
],
"defaultValue":"eastus2"
},
"workSpacePreffix":{
"type": "string",
"defaultValue":"mlw-",
"metadata":{
"description":" Machine Learning Workspace Prefix"
}
},
"workSpaceName": {
"type": "string",
"metadata": {
"description": "WorkSpace Name"
}
},
"deploymentName": {
"type": "string",
"defaultValue": "IacDSGroupResourceDeploymentV1",
"metadata": {
"description": "description"
}
}
},
"variables": {
"tenantId": "[subscription().tenantId]",
"hypenWorkSpaceName":"[toLower(replace(parameters('workSpaceName'), '_', '-'))]",
"validWorkSpaceName":"[toLower(replace(variables('hypenWorkSpaceName'), '-', ''))]",
"resourceGroupName":"[concat(parameters('grPrefix'), variables('hypenWorkSpaceName'))]",
"workSpaceFullName":"[concat(parameters('workSpacePreffix'), variables('hypenWorkSpaceName'))]",
"storageAccountName":"[concat('st', variables('validWorkSpaceName'))]",
"keyVaultName":"[concat(variables('hypenWorkSpaceName'), '-kv')]",
"applicationInsightsName":"[concat(variables('hypenWorkSpaceName'), '-ai')]",
"containerRegistryName":"[concat(variables('hypenWorkSpaceName'), 'cr')]"
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2024-03-01",
"name": "[variables('resourceGroupName')]",
"location": "[parameters('rgLocation')]",
"properties": {}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2024-03-01",
"name":"[parameters('deploymentName')]",
"resourceGroup":"[variables('resourceGroupName')]",
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', variables('resourceGroupName'))]"
],
"properties":{
"expressionEvaluationOptions": {
"scope": "Outer"
},
"mode": "Incremental",
"template":{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion":"1.0.0.0",
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-04-01",
"name": "[variables('storageAccountName')]",
"location": "[parameters('rgLocation')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2",
"properties": {
"encryption": {
"services": {
"blob": {
"enabled": true
},
"file": {
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"supportsHttpsTrafficOnly": true
}
},
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2019-09-01",
"name": "[variables('keyVaultName')]",
"location": "[parameters('rgLocation')]",
"properties": {
"tenantId": "[variables('tenantId')]",
"sku": {
"name": "standard",
"family": "A"
},
"enableSoftDelete": false,
"accessPolicies": []
}
},
{
"type": "Microsoft.Insights/components",
"apiVersion": "2020-02-02-preview",
"name": "[variables('applicationInsightsName')]",
"location": "[parameters('rgLocation')]",
"kind": "web",
"properties": {
"Application_Type": "web"
}
},
{
"type": "Microsoft.ContainerRegistry/registries",
"apiVersion": "2022-02-01-preview",
"name": "[variables('containerRegistryName')]",
"sku": {
"name": "Standard"
},
"location": "[parameters('rgLocation')]",
"properties": {
"adminUserEnabled": false
}
},
{
"type": "Microsoft.MachineLearningServices/workspaces",
"apiVersion": "2020-08-01",
"name": "[variables('workSpaceFullName')]",
"location": "[parameters('rgLocation')]",
"properties": {
"friendlyName": "[variables('workSpaceFullName')]",
"storageAccount": "[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"keyVault": "[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]",
"applicationInsights": "[resourceId('Microsoft.Insights/components', variables('applicationInsightsName'))]",
"containerRegistry": "[resourceId('Microsoft.ContainerRegistry/registries', variables('containerRegistryName'))]"
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', variables('storageAccountName'))]",
"[resourceId('Microsoft.KeyVault/vaults', variables('keyVaultName'))]",
"[resourceId('Microsoft.Insights/components', variables('applicationInsightsName'))]",
"[resourceId('Microsoft.ContainerRegistry/registries', variables('containerRegistryName'))]"
],
"identity": {
"type": "systemAssigned"
}
}
]
}
}
}
]
}
This template works fine for deploying a resource group and a storage account. However, I encounter errors when attempting to deploy multiple Azure Machine Learning services. My suspicion is that variables from the parent template are not being correctly passed to the child templates.
Any advice or insights would be greatly appreciated!
Thanks in advance for your help.
I tried adjusting the expressionEvaluationOptions:
"expressionEvaluationOptions": {
"scope": "Outer"
}
But received this error: Deployment template validation failed: 'The resource 'Microsoft.Storage/storageAccounts/stmyprojectname' is not defined in the template.
"expressionEvaluationOptions": {
"scope": "Inner"
}
Led to this error: Deployment template validation failed: 'The template variable 'storageAccountName' is not found. Please see https://aka.ms/arm-syntax-variables for usage details.
Here are the steps I've taken so far:
Inner
and Outer
scopes.I solved the problem with Azure Resource Manager (ARM) templates where variables defined at the subscription level were not being correctly passed to nested deployments. Specifically:
Solution
To resolve this, I declared the required variables again in Child1. This allowed Child2 to access them, even though this approach isn’t the most elegant.
Alternative Solution
Another approach would be to create the resource group first and then pass the resource group name to target resources for creation. This can be done in two steps using Azure DevOps or your preferred DevOps tool.
I hope this helps anyone facing a similar issue
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"grPrefix": {
"type": "string",
"defaultValue": "gr-mlw-"
},
"rgLocation": {
"type": "string",
"allowedValues": [
"eastus2",
"swedencentral",
"taiwannorth"
],
"defaultValue": "eastus2"
},
"workSpacePreffix": {
"type": "string",
"defaultValue": "mlw-",
"metadata": {
"description": "Machine Learning Workspace Prefix"
}
},
"workSpaceName": {
"type": "string",
"metadata": {
"description": "WorkSpace Name"
}
},
"deploymentName": {
"type": "string",
"defaultValue": "IacDSGroupResourceDeploymentV1",
"metadata": {
"description": "Deployment Name"
}
}
},
"variables": {
"tenantId": "[subscription().tenantId]",
"hypenWorkSpaceName": "[toLower(replace(parameters('workSpaceName'), '_', '-'))]",
"validWorkSpaceName": "[toLower(replace(variables('hypenWorkSpaceName'), '-', ''))]",
"resourceGroupName": "[concat(parameters('grPrefix'), variables('hypenWorkSpaceName'))]",
"workSpaceFullName": "[concat(parameters('workSpacePreffix'), variables('hypenWorkSpaceName'))]",
"storageAccountName": "[concat('st', variables('validWorkSpaceName'))]",
"keyVaultName": "[concat(variables('hypenWorkSpaceName'), '-kv')]",
"applicationInsightsName": "[concat(variables('validWorkSpaceName'), '-ai')]",
"containerRegistryName": "[concat(variables('validWorkSpaceName'), 'cr')]"
},
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2024-03-01",
"name": "[variables('resourceGroupName')]",
"location": "[parameters('rgLocation')]",
"properties": {}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2024-03-01",
"name": "[parameters('deploymentName')]",
"resourceGroup": "[variables('resourceGroupName')]",
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', variables('resourceGroupName'))]"
],
"properties": {
"***expressionEvaluationOptions***": {
"scope": "Inner"
},
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"storageAccountName": {
"type": "string"
},
"keyVaultName": {
"type": "string"
},
"applicationInsightsName": {
"type": "string"
},
"containerRegistryName": {
"type": "string"
},
"workSpaceFullName": {
"type": "string"
},
"location": {
"type": "string"
},
"tenantId": {
"type": "string"
}
},
"resources": [
{
"type": "Microsoft.Storage/storageAccounts",
"apiVersion": "2023-04-01",
"name": "[parameters('storageAccountName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard_LRS"
},
"kind": "StorageV2",
"properties": {
"encryption": {
"services": {
"blob": {
"enabled": true
},
"file": {
"enabled": true
}
},
"keySource": "Microsoft.Storage"
},
"supportsHttpsTrafficOnly": true
}
},
{
"type": "Microsoft.KeyVault/vaults",
"apiVersion": "2019-09-01",
"name": "[parameters('keyVaultName')]",
"location": "[parameters('location')]",
"properties": {
"tenantId": "[parameters('tenantId')]",
"sku": {
"name": "standard",
"family": "A"
},
"enableSoftDelete": false,
"accessPolicies": []
}
},
{
"type": "Microsoft.Insights/components",
"apiVersion": "2020-02-02-preview",
"name": "[parameters('applicationInsightsName')]",
"location": "[parameters('location')]",
"kind": "web",
"properties": {
"Application_Type": "web"
}
},
{
"type": "Microsoft.ContainerRegistry/registries",
"apiVersion": "2022-02-01-preview",
"name": "[parameters('containerRegistryName')]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard"
},
"properties": {
"adminUserEnabled": false
}
},
{
"type": "Microsoft.MachineLearningServices/workspaces",
"apiVersion": "2020-08-01",
"name": "[parameters('workSpaceFullName')]",
"location": "[parameters('location')]",
"properties": {
"friendlyName": "[parameters('workSpaceFullName')]",
"storageAccount": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
"keyVault": "[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]",
"applicationInsights": "[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]",
"containerRegistry": "[resourceId('Microsoft.ContainerRegistry/registries', parameters('containerRegistryName'))]"
},
"dependsOn": [
"[resourceId('Microsoft.Storage/storageAccounts', parameters('storageAccountName'))]",
"[resourceId('Microsoft.KeyVault/vaults', parameters('keyVaultName'))]",
"[resourceId('Microsoft.Insights/components', parameters('applicationInsightsName'))]",
"[resourceId('Microsoft.ContainerRegistry/registries', parameters('containerRegistryName'))]"
],
"identity": {
"type": "systemAssigned"
}
}
]
},
***"parameters"***: {
"storageAccountName": {
"value": "[variables('storageAccountName')]"
},
"keyVaultName": {
"value": "[variables('keyVaultName')]"
},
"applicationInsightsName": {
"value": "[variables('applicationInsightsName')]"
},
"containerRegistryName": {
"value": "[variables('containerRegistryName')]"
},
"workSpaceFullName": {
"value": "[variables('workSpaceFullName')]"
},
"location": {
"value": "[parameters('rgLocation')]"
},
"tenantId": {
"value": "[variables('tenantId')]"
}
}
}
}
]
}