{
  "properties": {
    "displayName": "Configure disaster recovery on virtual machines by enabling replication",
    "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. To learn more about disaster recovery, visit https://aka.ms/asr-doc.",
    "metadata": {
      "version": "1.2.0",
      "category": "Compute"
    },
    "parameters": {
      "sourceRegion": {
        "type": "String",
        "metadata": {
          "displayName": "Source Region",
          "description": "Region in which the virtual machine is originally 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 natural 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",
          "assignPermissions": true,
          "strongType": "Microsoft.Resources/resourceGroups",
          "serviceName": "ASR"
        }
      },
      "vaultResourceGroupId": {
        "type": "String",
        "metadata": {
          "displayName": "Vault Resource Group",
          "description": "The resource group containing the recovery services vault used for disaster recovery configurations",
          "assignPermissions": true,
          "strongType": "Microsoft.Resources/resourceGroups",
          "serviceName": "ASR"
        }
      },
      "vaultId": {
        "type": "String",
        "metadata": {
          "displayName": "Recovery Services Vault",
          "description": "ID of the 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": "Existing Recovery Virtual Network ID 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": ""
      },
      "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')]"
          },
          {
            "field": "Microsoft.Compute/virtualMachines/storageProfile.osDisk.vhd.uri",
            "exists": "false"
          },
          {
            "field": "Microsoft.Compute/virtualMachines/storageProfile.osDisk.encryptionSettings",
            "exists": "false"
          },
          {
            "anyOf": [
              {
                "allOf": [
                  {
                    "field": "location",
                    "equals": "[parameters('targetRegion')]"
                  },
                  {
                    "field": "Microsoft.Compute/virtualMachines/zones",
                    "exists": "true"
                  },
                  {
                    "field": "Microsoft.Compute/virtualMachines/zones[*]",
                    "notEquals": "[parameters('targetZone')]"
                  }
                ]
              },
              {
                "allOf": [
                  {
                    "field": "location",
                    "notEquals": "[parameters('targetRegion')]"
                  },
                  {
                    "field": "Microsoft.Compute/virtualMachines/zones",
                    "exists": "true"
                  },
                  {
                    "value": "[length(parameters('targetZone'))]",
                    "greater": 0
                  }
                ]
              },
              {
                "allOf": [
                  {
                    "field": "location",
                    "notEquals": "[parameters('targetRegion')]"
                  },
                  {
                    "field": "Microsoft.Compute/virtualMachines/zones",
                    "exists": "false"
                  }
                ]
              }
            ]
          }
        ]
      },
      "then": {
        "effect": "[parameters('effect')]",
        "details": {
          "type": "Microsoft.Resources/links",
          "roleDefinitionIds": [
            "/providers/Microsoft.Authorization/roleDefinitions/8e3af657-a8ff-443c-a75c-2fe8c4bcb635"
          ],
          "existenceCondition": {
            "allOf": [
              {
                "field": "name",
                "like": "ASR-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"
                  }
                },
                "variables": {
                  "avSetApiVersion": "2019-03-01",
                  "deploymentApiVersion": "2017-05-10",
                  "vmApiVersion": "2019-07-01",
                  "ppgApiVersion": "2019-12-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-",
                  "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'))]",
                  "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(greater(length(parameters('vmZones').rawValue), 0), 'AvailabilityZone', 'Single'))]",
                  "recoveryAvZone": "[if(greater(length(parameters('vmZones').rawValue), 0), 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'))]"
                },
                "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')]"
                    ]
                  },
                  {
                    "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": [
                          {
                            "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'), '\"', '}')), json(concat('{', '\"resourceType\"', ':', '\"New\",', '\"recoveryVirtualNetworkName\"', ':', '\"', parameters('recoveryNetworkId'), '\"', '}')))]",
                                "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')]"
                    ]
                  }
                ],
                "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": [

                    ]
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "id": "/providers/Microsoft.Authorization/policyDefinitions/ac34a73f-9fa5-4067-9247-a3ecae514468",
  "name": "ac34a73f-9fa5-4067-9247-a3ecae514468"
}