Related
I have an ARM template to deploy a sql.
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
......
"resources": [
{
"type": "Microsoft.Sql/servers",
"apiVersion": "2021-05-01-preview",
"name": "[parameters('serverName')]",
"location": "[parameters('location')]",
"properties": {
"administratorLogin": "[parameters('administratorLogin')]",
"administratorLoginPassword": "[parameters('administratorLoginPassword')]"
}
},
{
"type": "Microsoft.Sql/servers/databases",
"apiVersion": "2021-05-01-preview",
"name": "[format('{0}/{1}', parameters('serverName'), parameters('sqlDBName'))]",
"location": "[parameters('location')]",
"sku": {
"name": "Standard",
"tier": "Standard"
},
"dependsOn": [
"[resourceId('Microsoft.Sql/servers', parameters('serverName'))]"
]
}
]
}
When deployed it creates an empty sql database. How do we deploy the corresponding schema, tables, procedures?
We tested the below ARM template in our local environment it is working fine, Below statements are based on our analysis.
Here is the ARM template we have used to create a new SQL database, a table that is exported from the existing database.
Here is our template.json file:
{
"$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters":
{
"administratorLogin":
{
"type": "string"
},
"administratorLoginPassword":
{
"type": "securestring"
},
"databaseName":
{
"type": "string"
},
"location":
{
"type": "string"
},
"_artifactsLocationSasToken":
{
"type": "securestring"
}
},
"variables":
{
"collation": "SQL_Latin1_General_CP1_CI_AS",
"edition": "Premium",
"maxSizeBytes": "1073741824",
"requestedServiceObjectiveName": "P1",
"storageKeyType": "SharedAccessKey",
"version": "12.0",
"serverName": "[concat('sqldemo', uniqueString(resourceGroup().id))]"
},
"resources":
[
{
"name": "[variables('serverName')]",
"type": "Microsoft.Sql/servers",
"apiVersion": "2015-05-01-preview",
"location": "[parameters('location')]",
"properties":
{
"administratorLogin": "[parameters('administratorLogin')]",
"administratorLoginPassword": "[parameters('administratorLoginPassword')]",
"version": "[variables('version')]"
},
"resources":
[
{
"name": "AllowAllWindowsAzureIps",
"type": "firewallrules",
"apiVersion": "2015-05-01-preview",
"location": "[parameters('location')]",
"dependsOn":
[
"[concat('Microsoft.Sql/servers/', variables('serverName'))]"
],
"properties":
{
"endIpAddress": "0.0.0.0",
"startIpAddress": "0.0.0.0"
}
},
{
"name": "[parameters('databaseName')]",
"type": "databases",
"apiVersion": "2017-03-01-preview",
"location": "[parameters('location')]",
"dependsOn":
[
"[concat('Microsoft.Sql/servers/', variables('serverName'))]"
],
"properties":
{
"collation": "[variables('collation')]",
"edition": "[variables('edition')]",
"maxSizeBytes": "[variables('maxSizeBytes')]",
"requestedServiceObjectiveName": "[variables('requestedServiceObjectiveName')]"
},
"resources":
[
{
"name": "Import",
"type": "extensions",
"apiVersion": "2014-04-01-preview",
"dependsOn":
[
"[concat('Microsoft.Sql/servers/', variables('serverName'), '/databases/', parameters('databaseName'))]"
],
"properties":
{
"storageKeyType": "[variables('storageKeyType')]",
"storageKey": "[parameters('_artifactsLocationSasToken')]",
"storageUri": "<Storageuri_of_exported_bacpacfile>", ##pass the bloburi of the bacpac file
"administratorLogin": "[parameters('administratorLogin')]",
"administratorLoginPassword": "[parameters('administratorLoginPassword')]",
"operationMode": "Import"
}
}
]
}
]
}
],
"outputs":
{
"serverName":
{
"type": "object",
"value": "[reference(variables('serverName'))]"
}
}
}
Here is the template.parameters.json file :
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters":
{
"administratorLogin":
{
"value": "<sqlserverusername>"
},
"databaseName":
{
"value": "<dbtablename>"
},
"location":
{
"value": "<location>"
},
"_artifactsLocationSasToken":{
"value": "<SAS token of the exported bacpacfile>"
}
}
}
Here is the sample output for reference:
Note:
You need to create a firewall rule with your Public IP in the SQL database post-creating sql DB with a table using the above ARM template.
In most Azure resource private endpoints, I can configure them using a bicep script by calling 'Microsoft.Network/privateEndpoints'. With Purview, it has two kinds of private endpoints: the regular private endpoint and Ingestion private endpoint. When using the mentioned library, although I can create an endpoint, it is not shown under the Ingestion private endpoint connection name. If you do it through the portal, you will see that endpoint connection created there.
I also notice that there is another API named 'Microsoft.Purview/accounts/privateEndpointConnections' however, it only exposes two properties privateEndpoint.id and privateLinkServiceConnectionState - so this does not look like it will be appropriate to use either?
Therefore I wonder if anyone has tried to use Bicep to do the above? I realize that Purview Private endpoint is still under public preview so maybe there is no way to configure using Bicep yet. I also notice that we cannot export a Purview resource as an ARM template from the Azure Portal, so it leads me even more to believe that Bicep is not available for Purview? Just want to confirm with someone more knowledgeable in this before I decide to give up on it.
As Azure Purview is still In preview it is an evolving tool .
Below I am providing two ARM template one for Account and Portal endpoints and one for ingestion endpoints ( I have pasted here two ARM templates and there parametrized file)
Note :- Portal, Account and ingestion endpoint should be in same vnet and subnet
1-ARM template for Portal and account endpoint
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"type": "String"
},
"privateEndpointName-account": {
"type": "String"
},
"privateEndpointName-portal": {
"type": "String"
},
"purview_account_externalid": {
"type": "String"
},
"targetSubResource-account": {
"type": "Array"
},
"targetSubResource-portal": {
"type": "Array"
},
"subnet": {
"type": "String"
},
"virtualNetworkName": {
"type": "String"
},
"privateDnsDeploymentName": {
"type": "String"
},
"virtualNetworkLinkName": {
"type": "String"
},
"privateDNS": {
"type": "String"
}
},
"resources": [
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-03-01",
"name": "[parameters('privateEndpointName-account')]",
"location": "[parameters('location')]",
"tags": {
},
"properties": {
"subnet": {
"id": "[concat(resourceGroup().id, '/providers/Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'), '/subnets/', parameters('subnet'))]"
},
"privateLinkServiceConnections": [
{
"name": "[parameters('privateEndpointName-account')]",
"properties": {
"privateLinkServiceId": "[parameters('purview_account_externalid')]",
"groupIds": "[parameters('targetSubResource-account')]"
}
}
]
}
},
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-03-01",
"name": "[parameters('privateEndpointName-portal')]",
"location": "[parameters('location')]",
"tags": {
},
"properties": {
"subnet": {
"id": "[concat(resourceGroup().id, '/providers/Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'), '/subnets/', parameters('subnet'))]"
},
"privateLinkServiceConnections": [
{
"name": "[parameters('privateEndpointName-portal')]",
"properties": {
"privateLinkServiceId": "[parameters('purview_account_externalid')]",
"groupIds": "[parameters('targetSubResource-portal')]"
}
}
]
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"name": "[parameters('privateDnsDeploymentName')]",
"dependsOn": [
"[parameters('privateEndpointName-portal')]",
"[parameters('privateEndpointName-account')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"apiVersion": "2017-05-10",
"name": "[concat(parameters('privateDnsDeploymentName'), '-zone')]",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Network/privateDnsZones",
"apiVersion": "2018-09-01",
"name": "[parameters('privateDNS')]",
"location": "global",
"tags": {
},
"properties": {
}
}
]
}
}
}
]
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"name": "[parameters('virtualNetworkLinkName')]",
"dependsOn": [
"[parameters('privateDnsDeploymentName')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"apiVersion": "2017-05-10",
"name": "[concat(parameters('virtualNetworkLinkName'), '-link')]",
"type": "Microsoft.Resources/deployments",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Network/privateDnsZones/virtualNetworkLinks",
"apiVersion": "2018-09-01",
"name": "[concat(parameters('privateDNS'), '/', uniqueString(parameters('virtualNetworkName')))]",
"location": "global",
"properties": {
"virtualNetwork": {
"id": "[concat(resourceGroup().id, '/providers/Microsoft.Network/virtualNetworks/', parameters('virtualNetworkName'))]"
},
"registrationEnabled": false
}
}
]
}
}
}
]
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"name": "[concat(parameters('privateEndpointName-account'), '-', 'default')]",
"dependsOn": [
"[parameters('privateEndpointName-account')]",
"[parameters('privateDnsDeploymentName')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-03-01",
"name": "[concat(parameters('privateEndpointName-account'), '/', 'default')]",
"location": "[parameters('location')]",
"properties": {
"privateDnsZoneConfigs": [
{
"name": "[parameters('privateDNS')]",
"properties": {
"privateDnsZoneId": "[concat(resourceGroup().id, '/providers/Microsoft.Network/privateDnsZones/', parameters('privateDNS'))]"
}
}
]
}
}
]
}
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2017-05-10",
"name": "[concat(parameters('privateEndpointName-portal'), '-', 'default')]",
"dependsOn": [
"[parameters('privateEndpointName-portal')]",
"[parameters('privateDnsDeploymentName')]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-03-01",
"name": "[concat(parameters('privateEndpointName-portal'), '/', 'default')]",
"location": "[parameters('location')]",
"properties": {
"privateDnsZoneConfigs": [
{
"name": "[parameters('privateDNS')]",
"properties": {
"privateDnsZoneId": "[concat(resourceGroup().id, '/providers/Microsoft.Network/privateDnsZones/', parameters('privateDNS'))]"
}
}
]
}
}
]
}
}
}
]}
2- Parameterized file for Account and Portal Endpoints
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"location": {
"value": "Type the location of endpoint here"
},
"privateEndpointName-account": {
"value": "Type the name of Account endpoint here"
},
"privateEndpointName-portal": {
"value": "Type the name of Portal Endpoint here"
},
"purview_account_externalid": {
"value": "Go to azure portal > Purview >Properties >Resource Id,This is resource ID of the Purview "
},
"targetSubResource-account": {
"value": [
"account"
]
},
"targetSubResource-portal": {
"value": [
"portal"
]
},
"subnet": {
"value": "Type the name subnet here "
},
"virtualNetworkName": {
"value": "Type the name of the virtual network here "
},
"privateDnsDeploymentName": {
"value": "privatelink.purview.azure.com"
},
"virtualNetworkLinkName": {
"value": ""
},
"privateDNS": {
"value": "privatelink.purview.azure.com"
}
}}
3-ARM Template for Ingestion Endpoint
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ingestionEndpointName": {
"type": "String"
},
"purviewManagedRGId": {
"type": "String"
},
"virtualNetworksName": {
"type": "String"
},
"purviewManagedRGEventHubsNamespaceId": {
"type": "String"
},
"managedStorageAccountName": {
"type": "string"
},
"resourceGroupId": {
"type": "string"
},
"subnet": {
"type": "String"
},
"privateDnsZonesLinkBlob": {
"defaultValue": "privatelink.blob.core.windows.net",
"type": "String"
},
"privateDnsZonesLinkServicebus": {
"defaultValue": "privatelink.servicebus.windows.net",
"type": "String"
},
"privateDnsZonesLinkQueue": {
"defaultValue": "privatelink.queue.core.windows.net",
"type": "String"
}
},
"variables": {},
"resources": [
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-blob')]",
"location": "eastus",
"tags": {
"ContactEmail": "<not defined, please set>",
"ContactName": "<not defined, please set>",
"Department": "<not defined, please set>",
"Environment": "SANDBOX",
"OwnerName": "<not defined, please set>",
"Project": "<not defined, please set>"
},
"properties": {
"privateLinkServiceConnections": [
{
"name": "[concat(parameters('ingestionEndpointName'),'-blob')]",
"properties": {
"privateLinkServiceId": "[concat(parameters('purviewManagedRGId'),'/providers/Microsoft.Storage/storageAccounts/',parameters('managedStorageAccountName'))]",
"groupIds": [
"blob"
],
"privateLinkServiceConnectionState": {
"status": "Approved",
"description": "Auto-Approved",
"actionsRequired": "None"
}
}
}
],
"manualPrivateLinkServiceConnections": [],
"subnet": {
"id": "[concat(parameters('resourceGroupId'),'/providers/Microsoft.Network/virtualNetworks/',parameters('virtualNetworksName'), '/subnets/',parameters('subnet'))]"
},
"customDnsConfigs": []
}
},
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-namespace')]",
"location": "eastus",
"tags": {
"ContactEmail": "<not defined, please set>",
"ContactName": "<not defined, please set>",
"Department": "<not defined, please set>",
"Environment": "SANDBOX",
"OwnerName": "<not defined, please set>",
"Project": "<not defined, please set>"
},
"properties": {
"privateLinkServiceConnections": [
{
"name": "[concat(parameters('ingestionEndpointName'),'-namespace')]",
"properties": {
"privateLinkServiceId": "[parameters('purviewManagedRGEventHubsNamespaceId')]",
"groupIds": [
"namespace"
],
"privateLinkServiceConnectionState": {
"status": "Approved",
"description": "Auto-Approved",
"actionsRequired": "None"
}
}
}
],
"manualPrivateLinkServiceConnections": [],
"subnet": {
"id": "[concat(parameters('resourceGroupId'), '/providers/Microsoft.Network/virtualNetworks/',parameters('virtualNetworksName'), '/subnets/',parameters('subnet'))]"
},
"customDnsConfigs": []
}
},
{
"type": "Microsoft.Network/privateEndpoints",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-queue')]",
"location": "eastus",
"tags": {
"ContactEmail": "<not defined, please set>",
"ContactName": "<not defined, please set>",
"Department": "<not defined, please set>",
"Environment": "SANDBOX",
"OwnerName": "<not defined, please set>",
"Project": "<not defined, please set>"
},
"properties": {
"privateLinkServiceConnections": [
{
"name": "[concat(parameters('ingestionEndpointName'),'-queue')]",
"properties": {
"privateLinkServiceId": "[concat(parameters('purviewManagedRGId'),'/providers/Microsoft.Storage/storageAccounts/',parameters('managedStorageAccountName'))]",
"groupIds": [
"queue"
],
"privateLinkServiceConnectionState": {
"status": "Approved",
"description": "Auto-Approved",
"actionsRequired": "None"
}
}
}
],
"manualPrivateLinkServiceConnections": [],
"subnet": {
"id": "[concat(parameters('resourceGroupId'), '/providers/Microsoft.Network/virtualNetworks/',parameters('virtualNetworksName'), '/subnets/',parameters('subnet'))]"
},
"customDnsConfigs": []
}
},
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-blob','/default')]",
"dependsOn": [
"[resourceId('Microsoft.Network/privateEndpoints', concat(parameters('ingestionEndpointName'),'-blob'))]"
],
"properties": {
"privateDnsZoneConfigs": [
{
"name": "privatelink-blob-core-windows-net",
"properties": {
"privateDnsZoneId": "[concat(parameters('resourceGroupId'),'/providers/Microsoft.Network/privateDnsZones/',parameters('privateDnsZonesLinkBlob'))]"
}
}
]
}
},
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-namespace','/default')]",
"dependsOn": [
"[resourceId('Microsoft.Network/privateEndpoints', concat(parameters('ingestionEndpointName'),'-namespace'))]"
],
"properties": {
"privateDnsZoneConfigs": [
{
"name": "privatelink-servicebus-windows-net",
"properties": {
"privateDnsZoneId": "[concat(parameters('resourceGroupId'),'/providers/Microsoft.Network/privateDnsZones/',parameters('privateDnsZonesLinkServicebus'))]"
}
}
]
}
},
{
"type": "Microsoft.Network/privateEndpoints/privateDnsZoneGroups",
"apiVersion": "2020-11-01",
"name": "[concat(parameters('ingestionEndpointName'),'-queue','/default')]",
"dependsOn": [
"[resourceId('Microsoft.Network/privateEndpoints', concat(parameters('ingestionEndpointName'),'-queue'))]"
],
"properties": {
"privateDnsZoneConfigs": [
{
"name": "privatelink-queue-core-windows-net",
"properties": {
"privateDnsZoneId": "[concat(parameters('resourceGroupId'),'/providers/Microsoft.Network/privateDnsZones/',parameters('privateDnsZonesLinkQueue'))]"
}
}
]
}
}
]}
4- Parameterized file for Ingestion Endpoint template
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"ingestionEndpointName": {
"value": "Type the name of Ingestion Endpoint here"
},
"purviewManagedRGId": {
"value": "Go to azure portal > Purview> ManagedResource > Properties> Resource id This is the Resources ID of purview managed resource group"
},
"virtualNetworkName": {
"value": "Give the name of the Virtual network here"
},
"purviewManagedRGEventHubsNamespaceId": {
"value": "Go to azure portal > Purview>Managed Resource > Event Hubs namespace name>properties >Resource IDThis is Purview managed Event hub name space resources Id "
},
"managedStorageAccountName": {
"value": "Go to azure portal > Purview>Managed Resource > Storage Account"
},
"resourceGroupId": {
"value": "Go to azure portal > Purview> overview >resourceGroup"
},
"subnet": {
"value": "Give the name the subnet"
}
}}
How can I tag an Azure resource group using an ARM template and use Azure DevOps task Azure Deployment: Create Or Update Resource Group. I have error No HTTP resource was found that matches the request URI
{
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"customTags": {
"type": "object",
"defaultValue": {
"Environment Name": "TRdev",
"Environment Type":"Dev",
"Product family":"RT"
}
},
"rgName": {
"type": "string",
"defaultValue": "dev-rg",
"metadata": {
"description": "Name of the resourceGroup to create"
}
},
"serverfarms_environment_sp_sku": {
"defaultValue": "B1",
"allowedValues": [ "B1", "S1", "P1V2", "P2V2", "P3V2"],
"type": "String"
},
"serverfarms_environment_sp_name": {
"defaultValue": "dev-sp",
"type": "String"
},
"sites_environment_api_name": {
"defaultValue": "dev-api",
"type": "String"
},
"sites_environment_ui_name": {
"defaultValue": "dev-ui",
"type": "String"
}
},
"variables": { },
"resources": [
{
"type": "Microsoft.Resources/resourceGroups",
"apiVersion": "2018-05-01",
"location": "West US",
"name": "[parameters('rgName')]",
"tags": "[parameters('customTags')]",
"properties": {}
},
{
"apiVersion": "2019-08-01",
"name": "[parameters('rgName')]",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('rgName')]",
"tags": "[parameters('customTags')]",
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion": "1.0.0.1",
"parameters": {},
"resources": [
{
"apiVersion": "2018-02-01",
"type": "Microsoft.Web/serverfarms",
"kind": "app",
"name": "[parameters('serverfarms_environment_sp_name')]",
"location": "[resourceGroup().location]",
"tags": "[parameters('customTags')]",
"properties": {},
"dependsOn": [],
"sku": {
"name": "[parameters('serverfarms_environment_sp_sku')]"
}
},
{
"apiVersion": "2018-11-01",
"type": "Microsoft.Web/sites",
"kind": "app",
"name": "[parameters('sites_environment_api_name')]",
"location": "[resourceGroup().location]",
"tags": "[parameters('customTags')]",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_environment_sp_name'))]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_environment_sp_name'))]"
]
},
{
"apiVersion": "2018-11-01",
"type": "Microsoft.Web/sites",
"kind": "app",
"name": "[parameters('sites_environment_ui_name')]",
"location": "[resourceGroup().location]",
"tags": "[parameters('customTags')]",
"properties": {
"serverFarmId": "[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_environment_sp_name'))]"
},
"dependsOn": [
"[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_environment_sp_name'))]"
]
}
]
},
"parameters": {}
}
}
],
"outputs": {
"sites_environment_api_name": {
"type": "string",
"value": "[parameters('sites_environment_api_name')]"
},
"sites_environment_ui_name": {
"type": "string",
"value": "[parameters('sites_environment_ui_name')]"
}
}
}
Error
error No HTTP resource was found that matches the request URI 'https://management.azure.com/subscriptions/subscriptionsID/resourcegroups/resourcegroupsNeme/providers/Microsoft.Resources/resourceGroups/resourcegroupsNeme?api-version=2018-05-01'.
Thanks.
{
"type": "Microsoft.Resources/tags",
"name": "default",
"apiVersion": "2021-04-01",
"properties": {
"tags": "[variables('resourceTags')]"
}
}
You can apply tags to the target resource group by using the "tags" resource. In this case I've used a variable to store my default tags, but you could explicitly define them as well.
Checkout the following for more details:
https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/tag-resources?tabs=json#apply-tags-to-resource-groups-or-subscriptions
What you're trying to achieve is referred to as a subscription level deployment. If you are trying to deploy this through a template via the portal I'm afraid you're out of luck. The deployment UI insists you specify a resource group to deploy in to which invalidates the API path routing when making the call to create your resource group.
To overcome this you'll need to use PowerShell or the Azure CLI.
Another issue with subscription level deployments is that you can't use the resourceGroup() function, so your template will need be adjusted.
Your template should be:
{
"$schema":"https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion":"1.0.0.0",
"parameters":{
"customTags":{
"type":"object",
"defaultValue":{
"Environment Name":"TRdev",
"Environment Type":"Dev",
"Product family":"RT"
}
},
"rgName":{
"type":"string",
"defaultValue":"dev-rg",
"metadata":{
"description":"Name of the resourceGroup to create"
}
},
"serverfarms_environment_sp_sku":{
"defaultValue":"B1",
"allowedValues":[
"B1",
"S1",
"P1V2",
"P2V2",
"P3V2"
],
"type":"String"
},
"serverfarms_environment_sp_name":{
"defaultValue":"dev-sp",
"type":"String"
},
"sites_environment_api_name":{
"defaultValue":"dev-api",
"type":"String"
},
"sites_environment_ui_name":{
"defaultValue":"dev-ui",
"type":"String"
}
},
"variables":{
},
"resources":[
{
"type":"Microsoft.Resources/resourceGroups",
"apiVersion":"2018-05-01",
"location":"West US",
"name":"[parameters('rgName')]",
"tags":"[parameters('customTags')]",
"properties":{
}
},
{
"apiVersion":"2019-08-01",
"name":"[parameters('rgName')]",
"type":"Microsoft.Resources/deployments",
"resourceGroup":"[parameters('rgName')]",
"tags":"[parameters('customTags')]",
"dependsOn": [
"[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]"
],
"properties":{
"mode":"Incremental",
"template":{
"$schema":"https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
"contentVersion":"1.0.0.1",
"resources":[
{
"apiVersion":"2018-02-01",
"type":"Microsoft.Web/serverfarms",
"kind":"app",
"name":"[parameters('serverfarms_environment_sp_name')]",
"location":"[resourceGroup().location]",
"tags":"[parameters('customTags')]",
"properties":{
},
"dependsOn":[
],
"sku":{
"name":"[parameters('serverfarms_environment_sp_sku')]"
}
},
{
"apiVersion":"2018-11-01",
"type":"Microsoft.Web/sites",
"kind":"app",
"name":"[parameters('sites_environment_api_name')]",
"location":"[resourceGroup().location]",
"tags":"[parameters('customTags')]",
"properties":{
"serverFarmId":"[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_environment_sp_name'))]"
},
"dependsOn":[
"[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_environment_sp_name'))]"
]
},
{
"apiVersion":"2018-11-01",
"type":"Microsoft.Web/sites",
"kind":"app",
"name":"[parameters('sites_environment_ui_name')]",
"location":"[resourceGroup().location]",
"tags":"[parameters('customTags')]",
"properties":{
"serverFarmId":"[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_environment_sp_name'))]"
},
"dependsOn":[
"[resourceId('Microsoft.Web/serverfarms', parameters('serverfarms_environment_sp_name'))]"
]
}
]
},
}
}
],
"outputs":{
"sites_environment_api_name":{
"type":"string",
"value":"[parameters('sites_environment_api_name')]"
},
"sites_environment_ui_name":{
"type":"string",
"value":"[parameters('sites_environment_ui_name')]"
}
}
}
You can save this file to your local machine and deploy as follows.
PowerShell:
New-AzDeployment -TemplateFile '<path-to-template>' -Location 'West US'
Azure CLI:
az deployment create --template-file "<path-to-template>" --location "US West"
You will see a warning about upcoming breaking changes. Microsoft are introducing a mandatory parameter ScopeType to the PowerShell, and scope-type to the CLI with four possible values - ResourceGroup, Subscription, ManagementGroup and Tenant. In this instance, you would set ScopeType to Subscription, but you can see where Microsoft are going with the others.
I expect the portal template deployment UI will be updated soon.
Alternatively the ARM template can remain as is and have an additional step after to run just some simple powershell like:
Set-AzResourceGroup -Name "YOURRESOURCEGROUPNAME" -Tag #{Department="IT"}
This would allow you to maintain the current CI/CD structure.
More information on using Powershell to update the Resource Group
I'm trying to get the primaryConnectionStrings from an aRM template that creates multiple notification hubs
But I get this error
Error: Code=InvalidTemplate; Message=Deployment template validation failed: 'The template output 'connectionStrings' at line '291' and column '30' is not valid: The
template function 'copyIndex' is not expected at this location. The function can only be used in a resource with copy specified. Please see https://aka.ms/arm-copy for usage details.. Please see
https://aka.ms/arm-template-expressions for usage details.'.
I am clearly missing what this actually means as I've tried various incarnations of the template all of which have a copy for the resource.
I've tried this with a nested template (apologies if i've mangled the template, just removed some extraneous items):
"resources": [
{
"type": "Microsoft.NotificationHubs/namespaces",
"apiVersion": "2017-04-01",
"name": "[parameters('notificationHubName')]",
"location": "[resourceGroup().location]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Namespace"
},
"sku": {
"name": "[parameters('notificationHubSku')]"
},
"kind": "NotificationHub",
"properties": {
"namespaceType": "NotificationHub"
}
},
{
"type": "Microsoft.NotificationHubs/namespaces/AuthorizationRules",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/RootManageSharedAccessKey')]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Namespace Auth Rules"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
}
},
{
"type": "Microsoft.Resources/deployments",
"apiVersion": "2018-05-01",
"name": "[concat('nestedTemplate', copyIndex('notificationHubEntities'))]",
"copy": {
"name": "notificationHubEntities",
"count": "[length(parameters('notificationHubEntities'))]"
},
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/', parameters('notificationHubEntities')[copyIndex('notificationHubEntities')])]",
"location": "[resourceGroup().location]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hubs"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"authorizationRules": []
}
},
{
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs/authorizationRules",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/',parameters('notificationHubEntities')[copyIndex('notificationHubEntities')],'/DefaultFullSharedAccessSignature')]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Auth Rules"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces/notificationHubs',parameters('notificationHubName'), parameters('notificationHubEntities')[copyIndex('notificationHubEntities')])]",
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
}
},
],
"outputs" : {
"connectionString" : {
"type" : "object",
"value": "[listKeys(resourceId('Microsoft.NotificationHubs/namespaces/NotificationHubs/AuthorizationRules',parameters('notificationHubName'), parameters('notificationHubEntities')[copyIndex('notificationHubEntities')], 'DefaultFullSharedAccessSignature'),'2016-03-01').primaryConnectionString]"
}
}
}
}
}
],
"outputs": {
"connectionStrings" :
{
"type": "array",
"value": "[reference(concat('nestedTemplate', copyIndex('notificationHubEntities'))).outputs.connectionString.value]"
}
}
}
I've also tried with this:
"resources": [
{
"type": "Microsoft.NotificationHubs/namespaces",
"apiVersion": "2017-04-01",
"name": "[parameters('notificationHubName')]",
"location": "[resourceGroup().location]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Namespace"
},
"sku": {
"name": "[parameters('notificationHubSku')]"
},
"kind": "NotificationHub",
"properties": {
"namespaceType": "NotificationHub"
}
},
{
"type": "Microsoft.NotificationHubs/namespaces/AuthorizationRules",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/RootManageSharedAccessKey')]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Namespace Auth Rules"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
}
},
{
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/', parameters('notificationHubEntities')[copyIndex()])]",
"location": "[resourceGroup().location]",
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hubs"
},
"copy": {
"name": "addNotificationHub",
"count": "[length(parameters('notificationHubEntities'))]"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"authorizationRules": []
}
},
{
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs/authorizationRules",
"apiVersion": "2017-04-01",
"name": "[concat(parameters('notificationHubName'), '/',parameters('notificationHubEntities')[copyIndex()],'/DefaultFullSharedAccessSignature')]",
"copy": {
"name": "addNotificationHub",
"count": "[length(parameters('notificationHubEntities'))]"
},
"tags": {
"Environment": "[parameters('environment')]",
"DisplayName": "Notification Hub Auth Rules"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces/notificationHubs',parameters('notificationHubName'), parameters('notificationHubEntities')[copyIndex()])]",
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('notificationHubName'))]"
],
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
}
}
],
"outputs": {
"connectionStrings" :
{
"type": "array",
"value": "[listKeys(resourceId('Microsoft.NotificationHubs/namespaces/NotificationHubs/AuthorizationRules',parameters('notificationHubName'), parameters('notificationHubEntities')[copyIndex()], 'DefaultFullSharedAccessSignature'),'2016-03-01').primaryConnectionString]"
}
}
I've tried using object instead of array but to no avail, so I'm a bit confused, any help would be appreciated as the error message seems misleading to me or I'm just not interpreting it correctly.
To accomplish requirement of creating multiple notification hubs and it's authorization rules, you can use below ARM template.
Template Parameter File (notificationhub.parameters.json):
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"namespaceName": {
"value": "mm-namespace"
},
"notificationhubNamePrefix": {
"value": "mm-notificationhub"
},
"notificationhubAuthorizationruleNamePrefix": {
"value": "mm-notificationhubAuthorizationrule"
}
}
}
Template File (notificationhub.json):
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"namespaceName": {
"type": "string",
"defaultValue": "mm-namespace",
"metadata": {
"description": "namespaceName sample description"
}
},
"notificationhubNamePrefix": {
"type": "string",
"defaultValue": "mm-notificationhub",
"metadata": {
"description": "notificationhubName sample description"
}
},
"notificationhubAuthorizationruleNamePrefix": {
"type": "string",
"defaultValue": "mm-notificationhubAuthorizationrule",
"metadata": {
"description": "notificationhubAuthorizationruleName sample description"
}
},
"location": {
"type": "string",
"defaultValue": "[resourceGroup().location]",
"metadata": {
"description": "The location in which the resources should be deployed."
}
},
"notificationhubNameSuffix": {
"type": "array",
"defaultValue": [
"00",
"01",
"02"
]
},
"notificationhubAuthorizationruleNameSuffix": {
"type": "array",
"defaultValue": [
"00",
"01",
"02"
]
}
},
"variables": {},
"resources": [
{
"name": "[parameters('namespaceName')]",
"type": "Microsoft.NotificationHubs/namespaces",
"apiVersion": "2017-04-01",
"location": "[parameters('location')]",
"tags": {},
"sku": {
"name": "Free"
},
"properties": {
"namespaceType": "NotificationHub"
}
},
{
"name": "[concat(parameters('namespaceName'), '/', parameters('notificationhubNamePrefix'), parameters('notificationhubNameSuffix')[copyIndex()])]",
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs",
"apiVersion": "2017-04-01",
"location": "[parameters('location')]",
"sku": {
"name": "Free"
},
"copy": {
"name": "notificationhubscopy",
"count": "[length(parameters('notificationhubNameSuffix'))]"
},
"dependsOn": [
"[resourceId('Microsoft.NotificationHubs/namespaces', parameters('namespaceName'))]"
]
},
{
"name": "[concat(parameters('namespaceName'), '/', parameters('notificationhubNamePrefix'), parameters('notificationhubNameSuffix')[copyIndex()], '/', parameters('notificationhubAuthorizationruleNamePrefix'), parameters('notificationhubAuthorizationruleNameSuffix')[copyIndex()])]",
"type": "Microsoft.NotificationHubs/namespaces/notificationHubs/AuthorizationRules",
"apiVersion": "2017-04-01",
"properties": {
"rights": [
"Listen",
"Manage",
"Send"
]
},
"copy": {
"name": "notificationhubsauthroizationrulescopy",
"count": "[length(parameters('notificationhubAuthorizationruleNameSuffix'))]"
},
"dependsOn": [
"notificationhubscopy"
]
}
]
}
Deployment:
AFAIK, to accomplish requirement of getting output (in this case primaryConnectionStrings of multiple notification hubs' authorization rules) from ARM template is currently an unsupported feature. I already see related feature requests / feedback here and here. I would recommend you to up-vote these feature requests / feedback or create a new feature request / feedback explaining your use case and requirement. Azure feature team would consider and work on the feature request / feedback based on the votes, visibility and priority on it.
Azure document references:
ARM template reference for NotificationHubs
Resolve Invalid Template errors
Create multiple instances of a resource using copy and copyIndex
ARM template functions like list (ListKeys)
ARM template structure
Defining order for deploying resources in ARM templates
Hope this helps!! Cheers!!
You can't use a copy loop in outputs today - listing the keys is fine, but you have to know how many you need at design time and hardcode each output. We're working on a fix for that but not there yet.
You could emulate this by using your second option - deploying in a nested deployment and outputting each key in it's own deployment, but then you have to iterate through all the deployments to get all the outputs.
I'm trying to use the Recovery Services where I can automatically add a VM to Azure Backup via ARM template. I have successfully done this on a single machine deploy, but I'm trying to import it for when multiple VMs are deployed.
Here is where I had help from:
https://www.francoisdelport.com/2017/03/automating-azure-vm-backups-using-arm-templates/
and
Azure ARM JSON template - Add VM to Recovery Services Vault in different Resource Group
Here is a snippet from a single deploy I had working
{
"apiVersion": "2017-05-10",
"name": "nestedTemplate",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "Env1",
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/', variables('vmName'))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"apiVersion": "2016-06-01",
"name": "[concat( parameters('recoveryVault'), '/Azure/', 'iaasvmcontainer;iaasvmcontainerv2;', parameters('vmRsg') , ';', parameters('vmPrefix'), '/vm;iaasvmcontainerv2;', parameters('vmRsg'),';', parameters('vmPrefix'))]",
"location": "[resourceGroup().location]",
"type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems",
"properties": {
"protectedItemType": "Microsoft.Compute/virtualMachines",
"policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('recoveryVault'), parameters('recoveryPolicy'))]",
"sourceResourceId": "[resourceId(subscription().subscriptionId, parameters('vmRsg'), 'Microsoft.Compute/virtualMachines', parameters('vmPrefix'))]"
}
}
]
}
}
}
Now I'm trying to use that in a copyIndex form for VM deploy, and here is the code I've been testing with:
{
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"adminUsername": {
"type": "string",
"minLength": 1,
"metadata": {
"description": "Username for the Virtual Machine."
}
},
"adminPassword": {
"type": "securestring",
"metadata": {
"description": "Password for the Virtual Machine."
}
},
"dnsNameForPublicIP": {
"type": "string",
"minLength": 1,
"metadata": {
"description": "Globally unique DNS Name for the Public IP used to access the Virtual Machine."
}
},
"windowsOSVersion": {
"type": "string",
"defaultValue": "2012-R2-Datacenter",
"allowedValues": [
"2008-R2-SP1",
"2012-Datacenter",
"2012-R2-Datacenter"
],
"metadata": {
"description": "The Windows version for the VM. This will pick a fully patched image of this given Windows version. Allowed values: 2008-R2-SP1, 2012-Datacenter, 2012-R2-Datacenter."
}
},
"vmCount": {
"type": "int",
"defaultValue": 1
},
"virtualNetworkName": {
"type": "string"
},
"dataDiskCount": {
"type": "int",
"defaultValue": 1
},
"recoveryVault": {
"type": "string",
"metadata": {
"description": "Backup vault name"
}
},
"recoveryPolicy": {
"type": "string",
"metadata": {
"description": "Backcup policy name"
}
},
"vmPrefix": {
"type": "string",
"metadata": {
"description": "Prefix for VM names, used with vmCount to build the VM names"
}
},
"vmRsg": {
"type": "string",
"metadata": {
"description": "Resource group where VMs reside"
}
}
},
"variables": {
"imagePublisher": "MicrosoftWindowsServer",
"imageOffer": "WindowsServer",
"OSDiskName": "osdiskforwindowssimple",
"nicName": "myVMNic",
"subnetName": "Subnet",
"vhdStorageType": "Standard_LRS",
"publicIPAddressName": "myPublicIP",
"publicIPAddressType": "Dynamic",
"vhdStorageContainerName": "vhds",
"vmName": "MWindowsVM",
"vmSize": "Standard_A2",
"virtualNetworkName": "MyVNET",
"vnetId": "[resourceId(resourceGroup().name, 'Microsoft.Network/virtualNetworks', parameters('virtualNetworkName'))]",
"subnetRef": "[concat(variables('vnetId'), '/subnets/', variables('subnetName'))]"
},
"resources": [
{
"apiVersion": "2016-03-30",
"type": "Microsoft.Network/publicIPAddresses",
"name": "[concat(variables('publicIPAddressName'), copyIndex(1))]",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "PublicIPAddress"
},
"properties": {
"publicIPAllocationMethod": "[variables('publicIPAddressType')]",
"dnsSettings": {
"domainNameLabel": "[concat(parameters('dnsNameForPublicIP'), copyIndex(1))]"
}
},
"copy": {
"name": "publicIpCopy",
"count": "[parameters('vmCount')]"
}
},
{
"apiVersion": "2016-03-30",
"type": "Microsoft.Network/networkInterfaces",
"name": "[concat(variables('nicName'), copyIndex(1))]",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "NetworkInterface"
},
"dependsOn": [
"[concat('Microsoft.Network/publicIPAddresses/', concat(variables('publicIPAddressName'), copyIndex(1)))]"
],
"properties": {
"ipConfigurations": [
{
"name": "[concat('ipconfig', copyIndex(1))]",
"properties": {
"privateIPAllocationMethod": "Dynamic",
"publicIPAddress": {
"id": "[resourceId('Microsoft.Network/publicIPAddresses', concat(variables('publicIPAddressName'), copyIndex(1)))]"
},
"subnet": {
"id": "[variables('subnetRef')]"
}
}
}
]
},
"copy": {
"name": "nicCopy",
"count": "[parameters('vmCount')]"
}
},
{
"apiVersion": "2017-03-30",
"copy": {
"name": "nodeCopy",
"count": "[parameters('vmCount')]"
},
"type": "Microsoft.Compute/virtualMachines",
"name": "[concat(variables('vmName'), copyIndex(1))]",
"location": "[resourceGroup().location]",
"tags": {
"displayName": "VirtualMachine"
},
"dependsOn": [
"[resourceId('Microsoft.Network/networkInterfaces/', concat(variables('nicName'), copyIndex(1)))]"
],
"properties": {
"hardwareProfile": {
"vmSize": "[variables('vmSize')]"
},
"osProfile": {
"computerName": "[concat(variables('vmName'), copyIndex(1))]",
"adminUsername": "[parameters('adminUsername')]",
"adminPassword": "[parameters('adminPassword')]"
},
"storageProfile": {
"imageReference": {
"publisher": "[variables('imagePublisher')]",
"offer": "[variables('imageOffer')]",
"sku": "[parameters('windowsOSVersion')]",
"version": "latest"
},
"osDisk": {
"createOption": "FromImage"
},
"copy": [
{
"name": "dataDisks",
"count": "[parameters('dataDiskCount')]",
"input": {
"diskSizeGB": 1023,
"lun": "[copyIndex('dataDisks')]",
"createOption": "Empty"
}
}
]
},
"networkProfile": {
"networkInterfaces": [
{
"id": "[resourceId('Microsoft.Network/networkInterfaces', concat(variables('nicName'), copyIndex(1)))]"
}
]
}
}
},
{
"apiVersion": "2017-05-10",
"name": "nestedTemplate",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "Env1",
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/', concat(variables('vmName'), copyIndex(1)))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"copy": {
"name": "protectedItemsCopy",
"count": "[parameters('vmCount')]"
},
"apiVersion": "2017-03-30",
"name": "[concat( parameters('recoveryVault'), '/Azure/', 'iaasvmcontainer;iaasvmcontainerv2;', parameters('vmRsg') , ';', parameters('vmPrefix'), copyIndex(1), '/vm;iaasvmcontainerv2;', parameters('vmRsg'),';', parameters('vmPrefix'), copyIndex(1))]",
"location": "[resourceGroup().location]",
"type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems",
"properties": {
"protectedItemType": "Microsoft.Compute/virtualMachines",
"policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('recoveryVault'), parameters('recoveryPolicy'))]",
"sourceResourceId": "[resourceId(subscription().subscriptionId ,parameters('vmRsg'),'Microsoft.Compute/virtualMachines', concat(parameters('vmPrefix'), copyIndex(1)) )]"
}
}
]
}
}
}
]
}
Sadly it reports an error when trying to deploy, which I can't figure out why because it seems to be correct.
Error: Code=InvalidTemplate; Message=Deployment template validation failed: 'The template resource 'nestedTemplate' at line '198' and column '10' is not valid: The template function 'copyIndex' is not expected at this location. The function can only be used in a resource with copy specified. Please see https://aka.ms/arm-copy for usage details.. Please see https://aka.ms/arm-template-expressions for usage details.'.
The deployment validation failed
FYI, line 198 is "name": "nestedTemplate",
Any ideas, please?
To expand upon #4c74356b41 answer I was missing the all important "index":{ "value": "[copyIndex()]" within "Microsoft.Resources/deployments" on the parent template.
For those wanting to know more, have a look at: https://learn.microsoft.com/en-us/azure/azure-resource-manager/resource-group-create-multiple
Ensure you have the ('index') parameter next to those items which need to be duplicated, such as "[concat(parameters('WHATEVER'), parameters('index'))]"
I also ended up having a nested source within my linked template for the overall design I was looking for.
So my parent template had a linked (child) template (to another file) with:
name": "[concat('nestings', copyIndex(1))]",
"type": "Microsoft.Resources/deployments", ...
My child template had all the usual buildings of a VM with the parameters ('index') to ensure the items which are duplicated are named correctly.
And finally at the bottom of the child template I had a nested template source so I could back the VM up to another resource group (had to be nested, otherwise you can't do multiple resource groups), which looked like this:
{
"apiVersion": "2017-05-10",
"name": "[concat('nestedTemplate', parameters('index'))]",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "Env1",
"dependsOn": [
"[concat('Microsoft.Compute/virtualMachines/', concat(variables('vmName'), parameters('index')))]"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {},
"variables": {},
"resources": [
{
"apiVersion": "2016-06-01",
"name": "[concat( parameters('recoveryVault'), '/Azure/', 'iaasvmcontainer;iaasvmcontainerv2;', parameters('vmRsg') , ';', concat(parameters('vmPrefix'), parameters('index')), '/vm;iaasvmcontainerv2;', parameters('vmRsg'),';', concat(parameters('vmPrefix'), parameters('index')))]",
"location": "[resourceGroup().location]",
"type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems",
"properties": {
"protectedItemType": "Microsoft.Compute/virtualMachines",
"policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies', parameters('recoveryVault'), parameters('recoveryPolicy'))]",
"sourceResourceId": "[resourceId(subscription().subscriptionId, parameters('vmRsg'), 'Microsoft.Compute/virtualMachines', concat(parameters('vmPrefix'), parameters('index')))]"
}
}
]
}
}
}
So what its telling you that you are not supposed to use copyIndex() function in that place. Now why exactly this is happening I don't know, but I do know that inline templates are a mess (for instance they use parent template paremeters, not nested template), I'm pretty sure if you convert that template to a real nested template (so a linked template, completely separate file) the above syntax will work.
Also, I'm handling this in a separate manner. I'm using 1 single nested deployment for each VM I have, so I'm using copy on the deployment resource, not backup resource.