I\'m trying to add the functionality to add the VM to a recovery services vault to my existing Azure ARM JSON template that I use for deployment.
I\'ve used the code
If you are going to use that Nested Template make sure you add the VM that you provisioned in the first template as a DependsOn. This way when it runs the incremental deployment the VM is already there.
I've found the answer to this if it's useful to anyone else. As already mentioned the recovery services vault will use the same resource group as defined for the template. To be able to define a different template for the RSV this needs to be done using a nested template.
I have used the following nested template to replace the recovery services resource in my original post, the resource group required for the recovery services vault is defined by "resourceGroup": "[parameters('nestedTemplateRecoveryServicesResourceGroup')]",
{
"apiVersion": "2017-05-10",
"name": "nestedTemplateRecoveryServices",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('nestedTemplateRecoveryServicesResourceGroup')]",
"dependsOn": ["[concat('Microsoft.Compute/virtualMachines/', parameters('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": [
{
"name": "[concat(parameters('existingRecoveryServicesVault'), '/', variables('backupFabric'), '/', variables('v2VmContainer'), concat(parameters('existingVirtualMachinesResourceGroup'),';',parameters('existingVirtualMachines')), '/', variables('v2Vm'), concat(parameters('existingVirtualMachinesResourceGroup'),';',parameters('existingVirtualMachines')))]",
"apiVersion": "2016-06-01",
"location": "[resourceGroup().location]",
"type": "Microsoft.RecoveryServices/vaults/backupFabrics/protectionContainers/protectedItems",
"properties": {
"protectedItemType": "[variables('v2VmType')]",
"policyId": "[resourceId('Microsoft.RecoveryServices/vaults/backupPolicies',parameters('existingRecoveryServicesVault'),parameters('existingBackupPolicy') )]",
"sourceResourceId": "[resourceId(subscription().subscriptionId,parameters('existingVirtualMachinesResourceGroup'),'Microsoft.Compute/virtualMachines',parameters('existingVirtualMachines'))]"
}
}
]
},
"parameters": {},
"outputs": {}
}
}
Here's the JSON I use to achieve this - it scales when using copyIndex()...as included in the resource below. I've adapted this from Microsoft's own JSON template on the Azure Portal since they improved the VM deployment to include the option to backup during deployment.
I typically provide an array of VM names and I name other resources from those names using copy loops. Technically they're related to or children of the VM when being built so it seems most applicable to use the VM name as the basis of the name of an associated resource. I use copyIndex() to push in the name of the VM being iterated in that loop (index) which means all the sub-resources and nested templates can also use those parameters.
Anyway, this is the resource (a nested template, as you have to). Associated variables and parameters below.
{
"apiVersion": "2017-05-10",
"name": "[concat(parameters('virtualMachineNames')[copyIndex()], '-' , 'BackupIntent')]",
"type": "Microsoft.Resources/deployments",
"resourceGroup": "[parameters('DestinationRSVResourceGroup')]",
"copy": {
"name": "AzureBackupLoop",
"count": "[length(parameters('virtualMachineNames'))]"
},
"dependsOn": [
"NameOfPreviousLoop"
],
"properties": {
"mode": "Incremental",
"template": {
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"resources": [
{
"name": "[concat(parameters('DestinationRecoveryServicesVault'), '/', 'Azure', '/', variables('v2Vm'), resourceGroup().name, ';', parameters('virtualMachineNames')[copyIndex()])]",
"apiVersion": "2017-07-01",
"type": "Microsoft.RecoveryServices/vaults/backupFabrics/backupProtectionIntent",
"properties": {
"friendlyName": "[concat(parameters('virtualMachineNames')[copyIndex()], 'BackupIntent')]",
"protectionIntentItemType": "AzureResourceItem",
"policyId": "[resourceId(parameters('DestinationRSVResourceGroup'), 'Microsoft.RecoveryServices/vaults/backupPolicies', parameters('DestinationRecoveryServicesVault'), parameters('existingBackupPolicy'))]",
"sourceResourceId": "[resourceId(resourceGroup().name, 'Microsoft.Compute/virtualMachines', parameters('virtualMachineNames')[copyIndex()])]"
}
}
]
}
}
}
The variables section from this template looks as follows:
"variables": {
"v2Vm": "vm;iaasvmcontainerv2;",
},
And finally the parameters (relevant to this resource):
"parameters": {
"DestinationRecoveryServicesVault": {
"type": "string",
"metadata": {
"description": "Name of the recovery services vault that the VM is to be backed up in to."
}
},
"existingBackupPolicy": {
"type": "string",
"metadata": {
"description": "Name of the backup policy that the VM will use."
}
},
"DestinationRSVResourceGroup": {
"type": "string",
"metadata": {
"description": "Resource group of the RSV."
}
}
"virtualMachineNames": {
"type": "array",
"metadata": {
"description": "An array of names for the VMs."
}
},
},