Every organization has a disaster recovery plan. Very few have a tested one, and an untested DR plan is a document, not a capability. Azure Site Recovery makes the testing part cheap enough to actually do, which is honestly its most underrated feature: you can fail over into an isolated network, validate the application end to end, and clean up, all without touching production replication.
What ASR Does and Does Not Cover
ASR continuously replicates VM disks to a target region (Azure to Azure) or from VMware and physical servers into Azure. Crash consistent recovery points are created every five minutes, app consistent points on a schedule you define using VSS on Windows or pre and post scripts on Linux. What it does not do: replicate PaaS. Your SQL databases should use their own replication (failover groups, geo replication), storage accounts use GRS or object replication, and the DR story is the composition of all of these, with ASR handling the IaaS layer and a recovery plan orchestrating the sequence.
resource "azurerm_recovery_services_vault" "this" {
name = "rsv-dr-neu"
location = "northeurope"
resource_group_name = azurerm_resource_group.dr.name
sku = "Standard"
soft_delete_enabled = true
}
resource "azurerm_site_recovery_replication_policy" "this" {
name = "policy-24h"
resource_group_name = azurerm_resource_group.dr.name
recovery_vault_name = azurerm_recovery_services_vault.this.name
recovery_point_retention_in_minutes = 1440
application_consistent_snapshot_frequency_in_minutes = 240
}
resource "azurerm_site_recovery_replicated_vm" "app01" {
name = "app01-replica"
resource_group_name = azurerm_resource_group.dr.name
recovery_vault_name = azurerm_recovery_services_vault.this.name
source_recovery_fabric_name = "asr-fabric-weu"
source_vm_id = azurerm_linux_virtual_machine.app01.id
recovery_replication_policy_id = azurerm_site_recovery_replication_policy.this.id
source_recovery_protection_container_name = "container-weu"
target_recovery_fabric_id = azurerm_site_recovery_fabric.neu.id
target_recovery_protection_container_id = azurerm_site_recovery_protection_container.neu.id
target_resource_group_id = azurerm_resource_group.dr_workload.id
managed_disk {
disk_id = azurerm_linux_virtual_machine.app01.os_disk[0].id
staging_storage_account_id = azurerm_storage_account.cache.id
target_resource_group_id = azurerm_resource_group.dr_workload.id
target_disk_type = "Premium_LRS"
target_replica_disk_type = "Premium_LRS"
}
network_interface {
source_network_interface_id = azurerm_network_interface.app01.id
target_subnet_name = "snet-app"
recovery_public_ip_address_id = null
}
}
Recovery Plans: Failover as Code
A raw failover boots VMs. A recovery plan boots them in order with logic between: group one brings up domain controllers and DNS, group two the database tier, group three the applications, with Automation runbooks between groups handling the things scripts do better than humans at 3 AM: repointing DNS records, updating load balancer backends, adjusting connection strings in App Configuration, and posting status to the incident channel. Every manual step in your DR runbook is a candidate for a script attached to the plan, and each one you convert shrinks your real RTO.
Honest RPO and RTO
Your RPO for the IaaS layer is the replication lag ASR reports per VM, monitor it and alert when it exceeds your target, because sustained lag usually means the cache storage account or bandwidth is undersized. Your RTO is not what the document says, it is what the stopwatch said during the last test failover: boot time plus script time plus the human decision time at the top. Which brings us to the discipline that separates real DR from theater: a test failover every quarter, into an isolated VNet, with application owners logging in and validating function, and the duration and issues written down. The first test always finds something: a forgotten static IP, an agent missing, a hardcoded hostname. Better to find it on a calm Tuesday than during the real event.
Cheers
Osama
Leave a comment