last sync: 2021-Oct-25 16:02:14 UTC

Azure Policy definition

Configure disaster recovery on virtual machines by enabling replication via Azure Site Recovery

Name Configure disaster recovery on virtual machines by enabling replication via Azure Site Recovery
Azure Portal
Id ac34a73f-9fa5-4067-9247-a3ecae514468
Version 2.0.0
details on versioning
Category Compute
Microsoft docs
Description Virtual machines without disaster recovery configurations are vulnerable to outages and other disruptions. If the virtual machine does not already have disaster recovery configured, this would initiate the same by enabling replication using preset configurations to facilitate business continuity. You can optionally include/exclude virtual machines containing a specified tag to control the scope of assignment. To learn more about disaster recovery, visit https://aka.ms/asr-doc.
Mode Indexed
Type BuiltIn
Preview FALSE
Deprecated FALSE
Effect Default: DeployIfNotExists
Allowed: (DeployIfNotExists, Disabled)
Used RBAC Role
Role Name Role Id
Owner 8e3af657-a8ff-443c-a75c-2fe8c4bcb635
History
Date/Time (UTC ymd) (i) Change type Change detail
2021-10-08 15:47:40 change Major (1.2.0 > 2.0.0)
2021-03-24 14:32:48 change Minor (1.1.0 > 1.2.0)
2021-03-16 16:49:20 change Minor (1.0.0 > 1.1.0)
2021-01-22 09:14:53 add ac34a73f-9fa5-4067-9247-a3ecae514468
Used in Initiatives none
JSON Changes

JSON
{
  "displayName": "Configure disaster recovery on virtual machines by enabling replication via Azure Site Recovery",
  "policyType": "BuiltIn",
  "mode": "Indexed",
  "description": "Virtual machines without disaster recovery configurations are vulnerable to outages and other disruptions. If the virtual machine does not already have disaster recovery configured, this would initiate the same by enabling replication using preset configurations to facilitate business continuity.  You can optionally include/exclude virtual machines containing a specified tag to control the scope of assignment. To learn more about disaster recovery, visit https://aka.ms/asr-doc.",
  "metadata": {
    "version": "2.0.0",
    "category": "Compute"
  },
  "parameters": {
    "sourceRegion": {
      "type": "String",
      "metadata": {
        "displayName": "Source Region",
        "description": "Region in which the source virtual machine is deployed",
        "strongType": "location",
        "serviceName": "ASR"
      }
    },
    "targetRegion": {
      "type": "String",
      "metadata": {
        "displayName": "Target Region",
        "description": "Region to be used to deploy the virtual machine in case of a disaster",
        "strongType": "location",
        "serviceName": "ASR"
      }
    },
    "targetResourceGroupId": {
      "type": "String",
      "metadata": {
        "displayName": "Target Resource Group",
        "description": "Resource group to be used to create the virtual machine in the target region",
        "strongType": "Microsoft.Resources/resourceGroups",
        "assignPermissions": true,
        "serviceName": "ASR"
      }
    },
    "vaultResourceGroupId": {
      "type": "String",
      "metadata": {
        "displayName": "Vault Resource Group",
        "description": "The resource group containing the recovery services vault used for disaster recovery configurations",
        "strongType": "Microsoft.Resources/resourceGroups",
        "assignPermissions": true,
        "serviceName": "ASR"
      }
    },
    "vaultId": {
      "type": "String",
      "metadata": {
        "displayName": "Recovery Services Vault",
        "description": "Recovery services vault to be used for disaster recovery configurations",
        "strongType": "Microsoft.RecoveryServices/vaults",
        "serviceName": "ASR"
      }
    },
    "recoveryNetworkId": {
      "type": "String",
      "metadata": {
        "displayName": "Recovery Virtual Network",
        "description": "Id of an existing virtual network in the target region or name of the virtual network to be created in target region",
        "strongType": "Microsoft.Network/virtualNetworks",
        "serviceName": "ASR"
      },
      "defaultValue": ""
    },
    "targetZone": {
      "type": "String",
      "metadata": {
        "displayName": "Target Availability Zone",
        "description": "Availability zone in the designated target region to be used by virtual machines during disaster",
        "strongType": "zone",
        "serviceName": "ASR"
      },
      "defaultValue": ""
    },
    "cacheStorageAccountId": {
      "type": "String",
      "metadata": {
        "displayName": "Cache storage account",
        "description": "Existing cache storage account ID or prefix for the cache storage account name to be created in source region.",
        "strongType": "Microsoft.Storage/storageAccounts",
        "serviceName": "ASR"
      },
      "defaultValue": ""
    },
    "tagName": {
      "type": "String",
      "metadata": {
        "displayName": "Tag Name",
        "description": "Name of the tag to use for including or excluding VMs in the scope of this policy. This should be used along with the tag value parameter.",
        "serviceName": "ASR"
      },
      "defaultValue": ""
    },
    "tagValue": {
      "type": "Array",
      "metadata": {
        "displayName": "Tag Values",
        "description": "Values of the tag to use for including or excluding VMs in the scope of this policy (in case of multiple values, use a comma-separated list). This should be used along with the tag name parameter.",
        "serviceName": "ASR"
      },
      "defaultValue": []
    },
    "tagType": {
      "type": "String",
      "metadata": {
        "displayName": "Tag Type",
        "description": "Tag type can be either Inclusion Tag or Exclusion Tag. Inclusion tag type will make sure VMs with tag name and tag value are included in replication, Exclusion tag type will make sure VMs with tag name and tag value are excluded from replication.",
        "serviceName": "ASR"
      },
      "allowedValues": [
        "Inclusion",
        "Exclusion",
        ""
      ],
      "defaultValue": ""
    },
    "effect": {
      "type": "String",
      "metadata": {
        "displayName": "Effect",
        "description": "Enable or disable the execution of the policy"
      },
      "allowedValues": [
        "DeployIfNotExists",
        "Disabled"
      ],
      "defaultValue": "DeployIfNotExists"
    }
  },
  "policyRule": {
    "if": {
      "allOf": [
        {
          "field": "type",
          "equals": "Microsoft.Compute/virtualMachines"
        },
        {
          "field": "location",
          "equals": "[parameters('sourceRegion')]"
        },
        {
          "anyOf": [
            {
              "allOf": [
                {
                  "value": "[parameters('tagType')]",
                  "equals": "Inclusion"
                },
                {
                  "field": "[concat('tags[', parameters('tagName'), ']')]",
                  "in": "[parameters('tagValue')]"
                }
              ]
            },
            {
              "allOf": [
                {
                  "value": "[parameters('tagType')]",
                  "equals": "Exclusion"
                },
                {
                  "field": "[concat('tags[', parameters('tagName'), ']')]",
                  "notIn": "[parameters('tagValue')]"
                }
              ]
            },
            {
              "anyOf": [
                {
                  "value": "[empty(parameters('tagName'))]",
                  "equals": "true"
                },
                {
                  "value": "[empty(parameters('tagValue'))]",
                  "equals": "true"
                },
                {
                  "value": "[empty(parameters('tagType'))]",
                  "equals": "true"
                }
              ]
            }
          ]
        }
      ]
    },
    "then": {
      "effect": "[parameters('effect')]",
      "details": {
        "type": "Microsoft.Resources/links",
        "evaluationDelay": "PT15M",
        "roleDefinitionIds": [
          "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
        ],
        "existenceCondition": {
          "allOf": [
            {
              "field": "name",
              "like": "ASR-Policy-Protect-*"
            },
            {
              "field": "Microsoft.Resources/links/targetId",
              "contains": "/replicationProtectedItems/"
            }
          ]
        },
        "deployment": {
          "properties": {
            "mode": "incremental",
            "template": {
              "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
              "contentVersion": "1.0.0.0",
              "parameters": {
                "apiVersion": {
                  "type": "String"
                },
                "avSetId": {
                  "type": "String"
                },
                "dataDiskIds": {
                  "type": "object"
                },
                "osDiskId": {
                  "type": "String"
                },
                "ppgId": {
                  "type": "String"
                },
                "recoveryNetworkId": {
                  "type": "String"
                },
                "recoverySubscriptionId": {
                  "type": "String"
                },
                "sourceRegion": {
                  "type": "String"
                },
                "sourceResourceGroupName": {
                  "type": "String"
                },
                "targetRegion": {
                  "type": "String"
                },
                "targetResourceGroupName": {
                  "type": "String"
                },
                "targetZone": {
                  "type": "String"
                },
                "vaultName": {
                  "type": "String"
                },
                "vaultResourceGroupName": {
                  "type": "String"
                },
                "vmId": {
                  "type": "String"
                },
                "vmZones": {
                  "type": "Object"
                },
                "cacheStorageAccountId": {
                  "type": "String"
                }
              },
              "variables": {
                "avSetApiVersion": "2019-03-01",
                "deploymentApiVersion": "2017-05-10",
                "vmApiVersion": "2019-07-01",
                "ppgApiVersion": "2019-12-01",
                "storageAccountApiVersion": "2018-07-01",
                "portalLinkPrefix": "https://portal.azure.com/#@microsoft.onmicrosoft.com/resource",
                "schemaLink": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                "defaultAvSet": "defaultAvSet-asr",
                "defaultPPG": "defaultPPG-asr",
                "eligibilityResultsDefault": "default",
                "protectedItemSuffix": "-policy",
                "recoveryAvSetPrefix": "RecoveryAvSet-",
                "recoveryPPGPrefix": "RecoveryPPG-",
                "storagePrefix": "Storage-",
                "avSetType": "Microsoft.Compute/availabilitySets",
                "deploymentType": "Microsoft.Resources/deployments",
                "networkType": "Microsoft.Network/virtualNetworks",
                "ppgType": "Microsoft.Compute/proximityPlacementGroups",
                "replicationEligibilityResultsType": "Microsoft.RecoveryServices/replicationEligibilityResults",
                "storageType": "Microsoft.Storage/storageAccounts",
                "vaultType": "Microsoft.RecoveryServices/vaults",
                "avSetTemplateName": "[concat(variables('recoveryAvSetPrefix'), last(split(parameters('vmId'), '/')))]",
                "avSetTemplateName64": "[if(greater(length(variables('avSetTemplateName')), 64), substring(variables('avSetTemplateName'), 0, 64), variables('avSetTemplateName'))]",
                "ppgTemplateName": "[concat(variables('recoveryPPGPrefix'), last(split(parameters('vmId'), '/')))]",
                "ppgTemplateName64": "[if(greater(length(variables('ppgTemplateName')), 64), substring(variables('ppgTemplateName'), 0, 64), variables('ppgTemplateName'))]",
                "storageAccountTemplateName": "[concat(variables('storagePrefix'), last(split(parameters('vmId'), '/')))]",
                "storageAccountTemplateName64": "[concat(variables('storagePrefix'), uniqueString(variables('storageAccountTemplateName')))]",
                "replicationProtectedIntentTemplateName": "[concat('ASR-', parameters('sourceResourceGroupName'), '-', last(split(parameters('vmId'), '/')))]",
                "replicationProtectedIntentTemplateName64": "[if(greater(length(variables('replicationProtectedIntentTemplateName')), 64), substring(variables('replicationProtectedIntentTemplateName'), 0, 64), variables('replicationProtectedIntentTemplateName'))]",
                "vmDataDiskIds": "[array(parameters('dataDiskIds').rawValue)]",
                "vmDiskCount": "[add(length(variables('vmDataDiskIds')), int(1))]",
                "diskIds": "[concat(array(parameters('osDiskId')), array(parameters('dataDiskIds').rawValue))]",
                "vaultId": "[resourceId(parameters('vaultResourceGroupName'), variables('vaultType'), parameters('vaultName'))]",
                "eligibilityResultsId": "[extensionResourceId(parameters('vmId'), variables('replicationEligibilityResultsType'), variables('eligibilityResultsDefault'))]",
                "protectedIntentName": "[concat(parameters('vaultName'), '/', guid(resourceGroup().id, last(split(parameters('vmId'), '/'))), variables('protectedItemSuffix'))]",
                "recoveryAvSetName": "[if(empty(parameters('avSetId')), variables('defaultAvSet'), concat(last(split(parameters('avSetId'), '/')), '-asr'))]",
                "recoveryAvSetId": "[if(empty(parameters('avSetId')), '', resourceId(parameters('targetResourceGroupName'), variables('avSetType'), variables('recoveryAvSetName')))]",
                "recoveryAvType": "[if(not(empty(parameters('avSetId'))), 'AvailabilitySet', if(not(empty(parameters('targetZone'))), 'AvailabilityZone', 'Single'))]",
                "recoveryAvZone": "[parameters('targetZone')]",
                "recoveryPPGName": "[if(empty(parameters('ppgId')), variables('defaultPPG'), concat(last(split(parameters('ppgId'), '/')), '-asr'))]",
                "recoveryPPGId": "[if(empty(parameters('ppgId')), '', resourceId(parameters('targetResourceGroupName'), variables('ppgType'), variables('recoveryPPGName')))]",
                "targetResourceGroupId": "[concat('/subscriptions/', parameters('recoverySubscriptionId'), '/resourceGroups/', parameters('targetResourceGroupName'))]",
                "storageAccountSKUName": "Standard_LRS",
                "storageAccountKind": "Storage",
                "cacheStorageAccountArmId": "[if(empty(parameters('cacheStorageAccountId')),'',if(contains(parameters('cacheStorageAccountId'),'/'),parameters('cacheStorageAccountId'),resourceId(parameters('vaultResourceGroupName'), variables('storageType'), parameters('cacheStorageAccountId'))))]"
              },
              "resources": [
                {
                  "condition": "[not(empty(parameters('ppgId')))]",
                  "apiVersion": "[variables('deploymentApiVersion')]",
                  "name": "[variables('ppgTemplateName64')]",
                  "type": "Microsoft.Resources/deployments",
                  "resourceGroup": "[parameters('targetResourceGroupName')]",
                  "properties": {
                    "mode": "Incremental",
                    "template": {
                      "$schema": "[variables('schemaLink')]",
                      "contentVersion": "1.0.0.0",
                      "parameters": {},
                      "variables": {},
                      "resources": [
                        {
                          "condition": "[not(empty(parameters('ppgId')))]",
                          "type": "[variables('ppgType')]",
                          "name": "[variables('recoveryPPGName')]",
                          "apiVersion": "[variables('ppgApiVersion')]",
                          "location": "[parameters('targetRegion')]",
                          "properties": {
                            "proximityPlacementGroupType": "[if(empty(parameters('ppgId')), 'Standard', reference(parameters('ppgId'), variables('ppgApiVersion')).proximityPlacementGroupType)]"
                          }
                        }
                      ]
                    },
                    "parameters": {}
                  }
                },
                {
                  "condition": "[not(empty(parameters('avSetId')))]",
                  "apiVersion": "[variables('deploymentApiVersion')]",
                  "name": "[variables('avSetTemplateName64')]",
                  "type": "Microsoft.Resources/deployments",
                  "resourceGroup": "[parameters('targetResourceGroupName')]",
                  "properties": {
                    "mode": "Incremental",
                    "template": {
                      "$schema": "[variables('schemaLink')]",
                      "contentVersion": "1.0.0.0",
                      "parameters": {},
                      "variables": {},
                      "resources": [
                        {
                          "condition": "[not(empty(parameters('avSetId')))]",
                          "type": "[variables('avSetType')]",
                          "sku": {
                            "name": "[if(empty(parameters('avSetId')), 'Aligned', reference(parameters('avSetId'), variables('avSetApiVersion'), 'Full').sku.name)]"
                          },
                          "name": "[variables('recoveryAvSetName')]",
                          "apiVersion": "[variables('avSetApiVersion')]",
                          "location": "[parameters('targetRegion')]",
                          "tags": {},
                          "properties": {
                            "platformUpdateDomainCount": "[if(empty(parameters('avSetId')), '5', reference(parameters('avSetId'), variables('avSetApiVersion')).platformUpdateDomainCount)]",
                            "platformFaultDomainCount": "[if(empty(parameters('avSetId')), '2', reference(parameters('avSetId'), variables('avSetApiVersion')).platformFaultDomainCount)]",
                            "proximityPlacementGroup": "[if(empty(parameters('ppgId')), json('null'), json(concat('{', '\"id\"', ':', '\"', variables('recoveryPPGId'), '\"', '}')))]"
                          }
                        }
                      ]
                    },
                    "parameters": {}
                  },
                  "dependsOn": [
                    "[variables('ppgTemplateName64')]"
                  ]
                },
                {
                  "condition": "[and(not(empty(parameters('cacheStorageAccountId'))), not(contains(parameters('cacheStorageAccountId'), '/')))]",
                  "apiVersion": "[variables('deploymentApiVersion')]",
                  "name": "[variables('storageAccountTemplateName64')]",
                  "type": "Microsoft.Resources/deployments",
                  "resourceGroup": "[parameters('vaultResourceGroupName')]",
                  "properties": {
                    "mode": "Incremental",
                    "template": {
                      "$schema": "[variables('schemaLink')]",
                      "contentVersion": "1.0.0.0",
                      "parameters": {},
                      "variables": {},
                      "resources": [
                        {
                          "condition": "[and(not(empty(parameters('cacheStorageAccountId'))), not(contains(parameters('cacheStorageAccountId'), '/')))]",
                          "type": "[variables('storageType')]",
                          "name": "[parameters('cacheStorageAccountId')]",
                          "apiVersion": "[variables('storageAccountApiVersion')]",
                          "location": "[parameters('sourceRegion')]",
                          "sku": {
                            "name": "[variables('storageAccountSKUName')]"
                          },
                          "kind": "[variables('storageAccountKind')]",
                          "properties": {
                            "supportsHttpsTrafficOnly": true
                          }
                        }
                      ]
                    },
                    "parameters": {}
                  }
                },
                {
                  "apiVersion": "[variables('deploymentApiVersion')]",
                  "name": "[variables('replicationProtectedIntentTemplateName64')]",
                  "type": "Microsoft.Resources/deployments",
                  "resourceGroup": "[parameters('vaultResourceGroupName')]",
                  "properties": {
                    "mode": "Incremental",
                    "template": {
                      "$schema": "[variables('schemaLink')]",
                      "contentVersion": "1.0.0.0",
                      "parameters": {},
                      "variables": {},
                      "resources": [
                        {
                          "condition": "[lessOrEquals(length(reference(variables('eligibilityResultsId'), '2018-07-10').errors), int('0'))]",
                          "type": "Microsoft.RecoveryServices/vaults/replicationProtectionIntents",
                          "name": "[variables('protectedIntentName')]",
                          "apiVersion": "[parameters('apiVersion')]",
                          "properties": {
                            "providerSpecificDetails": {
                              "instanceType": "A2A",
                              "fabricObjectId": "[parameters('vmId')]",
                              "primaryLocation": "[parameters('sourceRegion')]",
                              "recoveryLocation": "[parameters('targetRegion')]",
                              "recoverySubscriptionId": "[parameters('recoverySubscriptionId')]",
                              "recoveryAvailabilityType": "[variables('recoveryAvType')]",
                              "recoveryAvailabilityZone": "[variables('recoveryAvZone')]",
                              "recoveryResourceGroupId": "[variables('targetResourceGroupId')]",
                              "recoveryAvailabilitySetCustomInput": "[if(empty(parameters('avSetId')), json('null'), json(concat('{', '\"resourceType\"', ':', '\"Existing\",', '\"recoveryAvailabilitySetId\"', ':', '\"', variables('recoveryAvSetId'), '\"', '}')))]",
                              "recoveryProximityPlacementGroupCustomInput": "[if(empty(parameters('ppgId')), json('null'), json(concat('{', '\"resourceType\"', ':', '\"Existing\",', '\"recoveryProximityPlacementGroupId\"', ':', '\"', variables('recoveryPPGId'), '\"', '}')))]",
                              "recoveryVirtualNetworkCustomInput": "[if(contains(parameters('recoveryNetworkId'), '/'), json(concat('{', '\"resourceType\"', ':', '\"Existing\",', '\"recoveryVirtualNetworkId\"', ':', '\"', parameters('recoveryNetworkId'), '\"', '}')),if(empty(parameters('recoveryNetworkId')), json('null'), json(concat('{', '\"resourceType\"', ':', '\"New\",', '\"recoveryVirtualNetworkName\"', ':', '\"', parameters('recoveryNetworkId'), '\"', '}'))))]",
                              "primaryStagingStorageAccountCustomInput": "[if(empty(variables('cacheStorageAccountArmId')),json('null'),json(concat('{', '\"resourceType\"', ':', '\"Existing\",', '\"azureStorageAccountId\"', ':', '\"', variables('cacheStorageAccountArmId'), '\"', '}')))]",
                              "vmDisks": [],
                              "copy": [
                                {
                                  "name": "vmManagedDisks",
                                  "count": "[variables('vmDiskCount')]",
                                  "input": {
                                    "diskId": "[if(equals(copyIndex('vmManagedDisks'), int(0)), reference(parameters('vmId'), variables('vmApiVersion')).storageProfile.osDisk.managedDisk.Id, variables('vmDataDiskIds')[sub(copyIndex('vmManagedDisks'), int(1))])]",
                                    "recoveryResourceGroupCustomInput": {
                                      "resourceType": "Existing",
                                      "recoveryResourceGroupId": "[variables('targetResourceGroupId')]"
                                    }
                                  }
                                }
                              ]
                            }
                          }
                        }
                      ],
                      "outputs": {
                        "vmName": {
                          "value": "[last(split(parameters('vmId'), '/'))]",
                          "type": "string"
                        },
                        "availabilitySetUrl": {
                          "value": "[if(empty(parameters('avSetId')), '', concat(variables('portalLinkPrefix'), variables('recoveryAvSetId')))]",
                          "type": "string"
                        },
                        "proximityPlacementGroupUrl": {
                          "value": "[if(empty(parameters('ppgId')), '', concat(variables('portalLinkPrefix'), variables('recoveryPPGId')))]",
                          "type": "string"
                        },
                        "replicationEligibilityResults": {
                          "value": "[reference(variables('eligibilityResultsId'), parameters('apiVersion'))]",
                          "type": "Object"
                        }
                      }
                    },
                    "parameters": {}
                  },
                  "dependsOn": [
                    "[variables('ppgTemplateName64')]",
                    "[variables('avSetTemplateName64')]",
                    "[variables('storageAccountTemplateName64')]"
                  ]
                }
              ],
              "outputs": {}
            },
            "parameters": {
              "apiVersion": {
                "value": "2018-07-10"
              },
              "avSetId": {
                "value": "[field('Microsoft.Compute/virtualMachines/availabilitySet.id')]"
              },
              "dataDiskIds": {
                "value": {
                  "rawValue": "[field('Microsoft.Compute/virtualMachines/storageProfile.dataDisks[*].managedDisk.id')]",
                  "emptyArray": []
                }
              },
              "osDiskId": {
                "value": "[field('Microsoft.Compute/virtualMachines/storageProfile.osDisk.managedDisk.id')]"
              },
              "ppgId": {
                "value": "[field('Microsoft.Compute/virtualMachines/proximityPlacementGroup.id')]"
              },
              "recoveryNetworkId": {
                "value": "[parameters('recoveryNetworkId')]"
              },
              "recoverySubscriptionId": {
                "value": "[subscription().subscriptionId]"
              },
              "sourceRegion": {
                "value": "[parameters('sourceRegion')]"
              },
              "sourceResourceGroupName": {
                "value": "[resourcegroup().Name]"
              },
              "targetRegion": {
                "value": "[parameters('targetRegion')]"
              },
              "targetResourceGroupName": {
                "value": "[last(split(parameters('targetResourceGroupId'), '/'))]"
              },
              "targetZone": {
                "value": "[parameters('targetZone')]"
              },
              "vaultName": {
                "value": "[last(split(parameters('vaultId'), '/'))]"
              },
              "vaultResourceGroupName": {
                "value": "[last(split(parameters('vaultResourceGroupId'), '/'))]"
              },
              "vmId": {
                "value": "[field('id')]"
              },
              "vmZones": {
                "value": {
                  "rawValue": "[field('Microsoft.Compute/virtualMachines/zones')]",
                  "emptyArray": []
                }
              },
              "cacheStorageAccountId": {
                "value": "[parameters('cacheStorageAccountId')]"
              }
            }
          }
        }
      }
    }
  }
}