terraformterraform-provider-azureazure-site-recovery

Azure site recovery using Terraform: Updating replicated vm: polling after Update: Code="28020" Message="The requested operation failed."


I am trying to set up the "Azure Site Recovery" for Azure VM using Terraform. The Terraform configuration is correct and it works fine if "Azure Firewall" isn't deployed in the Virtual network. However, with Firewall deployed; Terraform could not verify the status of replication even after the successful creation of Replication. Do any network-related changes need to be done here?

Terrafrom Version: 1.5.0 Azurerm Version: 3.62.0

    `resource "azurerm_site_recovery_fabric" "primary" {
  name                = "asr-fabric-primary-${var.postfix}"
  location            = var.location
  recovery_vault_name = azurerm_recovery_services_vault.vault[0].name
  resource_group_name = module.resource_group_dr.resource_group.utilities.name
}

resource "azurerm_site_recovery_fabric" "secondary" {
  name                = "asr-fabric-secondary-${var.postfix}"
  location            = var.location_secondary
  recovery_vault_name = azurerm_recovery_services_vault.vault[0].name
  resource_group_name = module.resource_group_dr.resource_group.utilities.name
}

resource "azurerm_site_recovery_protection_container" "primary" {
  name                 = "asr-protection-container-primary-${var.postfix}"
  recovery_fabric_name = azurerm_site_recovery_fabric.primary.name
  recovery_vault_name  = azurerm_recovery_services_vault.vault[0].name
  resource_group_name  = module.resource_group_dr.resource_group.utilities.name
}

resource "azurerm_site_recovery_protection_container" "secondary" {
  name                 = "asr-protection-container-secondary-${var.postfix}"
  recovery_fabric_name = azurerm_site_recovery_fabric.secondary.name
  recovery_vault_name  = azurerm_recovery_services_vault.vault[0].name
  resource_group_name  = module.resource_group_dr.resource_group.utilities.name
}

resource "azurerm_site_recovery_network_mapping" "network_mapping_primary_to_secondary" {
  name                        = "asr-protection-container-mapping-primary-${var.postfix}"
  recovery_vault_name         = azurerm_recovery_services_vault.vault[0].name
  resource_group_name         = module.resource_group_dr.resource_group.utilities.name
  source_recovery_fabric_name = azurerm_site_recovery_fabric.primary.name
  target_recovery_fabric_name = azurerm_site_recovery_fabric.secondary.name
  source_network_id           = module.vnet_spoke.vnet.spoke1.id
  target_network_id           = module.vnet_spoke_dr.vnet.spoke1.id
}


resource "azurerm_site_recovery_network_mapping" "network_mapping_secondary_to_primary" {
  name                        = "asr-protection-container-mapping-secondary-${var.postfix}"
  recovery_vault_name         = azurerm_recovery_services_vault.vault[0].name
  resource_group_name         = module.resource_group_dr.resource_group.utilities.name
  source_recovery_fabric_name = azurerm_site_recovery_fabric.secondary.name
  target_recovery_fabric_name = azurerm_site_recovery_fabric.primary.name
  source_network_id           = module.vnet_spoke_dr.vnet.spoke1.id
  target_network_id           = module.vnet_spoke.vnet.spoke1.id
}

resource "azurerm_site_recovery_protection_container_mapping" "container_mapping" {
  name                                      = "container-mapping"
  resource_group_name                       = module.resource_group_dr.resource_group.utilities.name
  recovery_vault_name                       = azurerm_recovery_services_vault.vault[0].name
  recovery_fabric_name                      = azurerm_site_recovery_fabric.primary.name
  recovery_source_protection_container_name = azurerm_site_recovery_protection_container.primary.name
  recovery_target_protection_container_id   = azurerm_site_recovery_protection_container.secondary.id
  recovery_replication_policy_id            = azurerm_site_recovery_replication_policy.policy.id
}

resource "azurerm_site_recovery_replication_policy" "policy" {
  name                                                 = "${var.replication_policy.name}-${var.postfix}"
  resource_group_name                                  = module.resource_group_dr.resource_group.utilities.name
  recovery_vault_name                                  = azurerm_recovery_services_vault.vault[0].name
  recovery_point_retention_in_minutes                  = var.replication_policy.recovery_point_retention_in_minutes
  application_consistent_snapshot_frequency_in_minutes = var.replication_policy.application_consistent_snapshot_frequency_in_minutes
}


// Azure Site Recovery: Windows Bastion VM
data "azurerm_managed_disk" "os_disk_vm_win_bastion" {
  depends_on = [
    module.vm_win_bastion,
  ]
  name                = module.vm_win_bastion[0].windows_vm.os_disk[0].name
  resource_group_name = module.vm_win_bastion[0].windows_vm.resource_group_name
}

resource "azurerm_site_recovery_replicated_vm" "windows_bastion" {
  name                           = "asr-vm-windows-bastion"
  recovery_replication_policy_id = azurerm_site_recovery_replication_policy.policy.id
  recovery_vault_name            = azurerm_recovery_services_vault.vault[0].name
  resource_group_name            = module.resource_group_dr.resource_group.utilities.name

  source_recovery_fabric_name               = azurerm_site_recovery_fabric.primary.name
  source_recovery_protection_container_name = azurerm_site_recovery_protection_container.primary.name
  source_vm_id                              = module.vm_win_bastion[0].windows_vm.id

  target_recovery_fabric_id               = azurerm_site_recovery_fabric.secondary.id
  target_recovery_protection_container_id = azurerm_site_recovery_protection_container.secondary.id
  target_resource_group_id                = module.resource_group_dr.resource_group.treasury.id
  target_availability_set_id              = null
  target_zone                             = null
  target_network_id                       = module.vnet_spoke_dr.vnet.spoke1.id


  managed_disk {
    disk_id                    = data.azurerm_managed_disk.os_disk_vm_win_bastion.id
    staging_storage_account_id = module.storage_account_asr_cache[0].storage_account_id
    target_resource_group_id   = module.resource_group_dr.resource_group.treasury.id
    target_disk_type           = data.azurerm_managed_disk.os_disk_vm_win_bastion.storage_account_type
    target_replica_disk_type   = data.azurerm_managed_disk.os_disk_vm_win_bastion.storage_account_type
  }

  network_interface {
    source_network_interface_id   = module.vm_win_bastion[0].vm_nic_id
    target_subnet_name            = module.subnet_dr.subnet.vm-subnet.id
    target_static_ip              = null
    recovery_public_ip_address_id = null

  }

  depends_on = [
    azurerm_site_recovery_network_mapping.network_mapping_primary_to_secondary,
    azurerm_site_recovery_network_mapping.network_mapping_secondary_to_primary,
    azurerm_site_recovery_protection_container_mapping.container_mapping,
    azurerm_site_recovery_replication_policy.policy,
    azurerm_role_assignment.recovery_vaut_storage,
  ]

  lifecycle {
    ignore_changes = [
      target_network_id,
      source_vm_id,
    ]

  }
}

Solution

    1. There is a configuration mistake. I was passing 'Subnet ID' instead of 'Subnet Name'. correct configuration should be:

      target_subnet_name = module.subnet_dr.subnet.vm-subnet.name

    2. Another important thing is the ASR doesn't work with the VM disks that are not mounted and the file system is not created.