0

I am trying to configure the Disaster Recovery of our azure Windows Virtual Machines in "West Europe" to "North Europe" region using terraform. And we are using azurerm_site_recovery_replicated_vm for that, but I am getting problem in encryption part.

  • On our windows VM configuration, we are using azurem_virtual_machine_extension "AzureDiskEncryption" for the encryption of disks.
### azurem_virtual_machine_extension 
 win_s_01_ext04 = {
      name                       = "AzureDiskEncryption"
      virtual_machine_id         = module.virtual_machine_servers.0.windows_virtual_machines["win_s_01"].id
      publisher                  = "Microsoft.Azure.Security"
      type                       = "AzureDiskEncryption"
      type_handler_version       = "2.2"
      auto_upgrade_minor_version = true
      automatic_upgrade_enabled  = null
      settings                   = <<SETTINGS
        {
          "EncryptionOperation": "EnableEncryption",
          "KeyVaultURL": "${data.azurerm_key_vault.enc_kv.vault_uri}",
          "KeyVaultResourceId": "${data.azurerm_key_vault.enc_kv.id}",
          "KeyEncryptionKeyURL": "${data.azurerm_key_vault_key.enc_kv.id}",
          "KekVaultResourceId":  "${data.azurerm_key_vault.enc_kv.id}",
          "KeyEncryptionAlgorithm": "RSA-OAEP",
          "VolumeType": "All"
        }
      SETTINGS
      protected_settings         = null
      tags                       = module.tagging.module_tags
      depends_on = [
        module.virtual_machine_servers.0.windows_virtual_machines["win_s_01"].id
      ]
    }
  • When I tried to create azurerm_site_recovery_replicated_vm there is a required parameter for "Key vault Secret URL" and it needs to be the exact one used to encrypt on the original disks in "West Europe".And the problem is there are no option to specify what "keyvault secret URL" to be used when creating the VM and disk using the "AzureDiskEncryption" extension so it created/used random secret URL like this "secretUrl": "https://we-kv-prod-01.vault.azure.net/secrets/016CFB82-C29B-4542-A887-9B1F0BFD985A/2de208f261ee4e24a445669ae86a63f4".

For the meantime, I tried to copy manually the Keyvault secret URL in "West Europe" to "North Europe" that is being used by the os disk VM encryption and call it using data so the secret url in North Europe will be like this ""secretUrl": "https://we-kv-prod-01-asr.vault.azure.net/secrets/016CFB82-C29B-4542-A887-9B1F0BFD985A/2de208f261ee4e24a445669ae86a63f4"".

### DATA
data "azurerm_key_vault_secret" "asr_enc_kv" {
  provider     = azurerm.APPS_EU_PROD
  name         = "2506512E-84FA-464C-A802-2E64F16DB384"
  key_vault_id = data.azurerm_key_vault.asr_enc_kv.id
}

### azurerm_site_recovery_replicated_vm 
managed_disk = [
        {
          disk_id                       = data.azurerm_managed_disk.osdisk_01.id
          staging_storage_account_id    = data.azurerm_storage_account.rsv.id
          target_resource_group_id      = module.resource_group_asr.0.resource_groups["rg_asr_01"].id
          target_disk_type              = "Standard_LRS"
          target_replica_disk_type      = "Standard_LRS"
          target_disk_encryption_set_id = null
          target_disk_encryption = [
            {
              disk_encryption_key = [
                {
                  secret_url = data.azurerm_key_vault_secret.asr_enc_kv.id
                  vault_id   = data.azurerm_key_vault.asr_enc_kv.id
                }
              ]
              key_encryption_key = [
                {
                  key_url  = data.azurerm_key_vault_key.asr_enc_kv.id
                  vault_id = data.azurerm_key_vault.asr_enc_kv.id
                }
              ]
            }
          ]
        }

Does anyone know how can I replicate the "Key vault secret URL" in "North Europe" region using terraform and without doing any manual configuration. Or maybe give me some idea on how to handle the encryption for azurerm_site_recovery_replicated_vm?

Thanks in advance!

1 Answers1

0

As Source virtual machine data will be replicated in the target region.Make sure to have Key Vault in the same region as your target.

Make sure you have permissions on the source and target region key vault.

Here the new keyvault should also be created in target region and then the source secret must be used in target key vault:

Retrieve the key vault secret from the "West Europe" region Here the keyvault used is created in source region that is west europe

resource "azurerm_key_vault" "asr_enc_kv" {
  name                = "mykakey-vault"
  resource_group_name = “primary kvname”
  location            = “West Europe”
  sku_name            = "standard"

  tenant_id     = data.azurerm_client_config.current.tenant_id
  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = azurerm_virtual_machine.vm.identity.0.principal_id

    key_permissions = [
      "Get",
      "Create",
      "Delete",
      "List",
      "Recover",
      "Restore",
      "UnwrapKey",
      "WrapKey",
    ]

    secret_permissions = [
      "get",
  "list",
  "set",
  "delete",
  "recover",
  "restore",
]
}
}
data "azurerm_key_vault_secret" "original" {
  name         = "<original_secret_name>"
  key_vault_id = "<original_key_vault_id>"
}

There is a limitation for azure keyvault, that the secrets can’t be moved or replicated within the regions: We can only copy each secret manually .see Move a key vault to a different region - Azure Key Vault | Microsoft Learn

But as you are trying to back up the secrets, it may be good option to create new secret in the new region as a part of secure backup.

Create the replicated key vault secret in the "North Europe" region Here the keyvault used is created in north europe region.

resource "azurerm_key_vault_secret" "replicated" {
  name         = data.azurerm_key_vault_secret.original.name
  value        = data.azurerm_key_vault_secret.original.value
  key_vault_id = "<replicated_key_vault_id>"
}

resource "azurerm_site_recovery_replicated_vm" "vm-replication" {
  name                                      = "kavm-replication"
  resource_group_name                       = azurerm_resource_group.secondary.name
  recovery_vault_name                       = azurerm_recovery_services_vault.vault.name
  source_recovery_fabric_name               = azurerm_site_recovery_fabric.primary.name
  source_vm_id                              = azurerm_virtual_machine.vm.id
  recovery_replication_policy_id            = azurerm_site_recovery_replication_policy.policy.id
  source_recovery_protection_container_name = azurerm_site_recovery_protection_container.primary.name

  target_resource_group_id                = azurerm_resource_group.secondary.id
  target_recovery_fabric_id               = azurerm_site_recovery_fabric.secondary.id
  target_recovery_protection_container_id = azurerm_site_recovery_protection_container.secondary.id

_
  managed_disk      {
          disk_id                       = data.azurerm_managed_disk.osdisk_01.id
          staging_storage_account_id    = data.azurerm_storage_account.rsv.id
          target_resource_group_id   = azurerm_resource_group.secondary.id
          target_disk_type           = "Premium_LRS"
          target_replica_disk_type   = "Premium_LRS"
          target_disk_encryption_set_id = null
          target_disk_encryption = [
            {
              disk_encryption_key = [
                {
                  secret_url = azurerm_key_vault_secret. replicated.id
                  vault_id   = azurerm_key_vault. replicated.id
                }
              ]
              key_encryption_key = [
                {
                  key_url  = azurerm_key_vault_key. replicated.id
                  vault_id = azurerm_key_vault. replicated.id
                }
              ]
            }
          ]
        }
  
  

  network_interface {
    source_network_interface_id   = azurerm_network_interface.vm.id
    target_subnet_name            = azurerm_subnet.secondary.name
    recovery_public_ip_address_id = azurerm_public_ip.secondary.id
  }

  depends_on = [
    azurerm_site_recovery_protection_container_mapping.container-mapping,
    azurerm_site_recovery_network_mapping.network-mapping,
  ]
}

enter image description here

Even tried to copy same secret values to different region, the values will be same but the version will be varied and encryption varies and so the url doesn't remain same.

resource "azurerm_key_vault" "org" {
  name                       = "kkkkexamplekeyvault"
  location                   = data.azurerm_resource_group.example.location
  resource_group_name        = data.azurerm_resource_group.example.name
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  sku_name                   = "premium"
  soft_delete_retention_days = 7

  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = data.azurerm_client_config.current.object_id

    key_permissions = [
      "Get",
      "Create",
      "Delete",
      "List",
      "Recover",
      "Restore",
      "UnwrapKey",
      "WrapKey",
      "List"
    ]

    secret_permissions = [
      "Get",
  "List",
  "Set",
  "Delete",
  "Recover",
  "Restore",
]
  }
}

resource "azurerm_key_vault_secret" "org" {
  name         = "secret-sauce"
  value        = "szechuan"
  key_vault_id = azurerm_key_vault.org.id
}



resource "azurerm_key_vault" "copyorg" {
  name                       = "copyexamplekeyvault"
  location                   = "North Europe"
  resource_group_name        = data.azurerm_resource_group.example.name
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  sku_name                   = "premium"
  soft_delete_retention_days = 7

  access_policy {
    tenant_id = data.azurerm_client_config.current.tenant_id
    object_id = data.azurerm_client_config.current.object_id

    key_permissions = [
      "Get",
      "Create",
      "Delete",
      "List",
      "Recover",
      "Restore",
      "UnwrapKey",
      "WrapKey",
      "List"
    ]

    secret_permissions = [
      "Get",
  "List",
  "Set",
  "Delete",
  "Recover",
  "Restore",
]
  }
}

resource "azurerm_key_vault_secret" "copyorg" {
  name         = azurerm_key_vault_secret.org.name
  value        = azurerm_key_vault_secret.org.value
  
  key_vault_id = azurerm_key_vault.copyorg.id
  depends_on = [ azurerm_key_vault_secret.org, azurerm_key_vault.copyorg ]
}

enter image description here

enter image description here

when tried to replicate version: resource "azurerm_key_vault_secret" "copyorg" { name = azurerm_key_vault_secret.org.name value = azurerm_key_vault_secret.org.value version = azurerm_key_vault_secret.org.version

key_vault_id = azurerm_key_vault.copyorg.id depends_on = [ azurerm_key_vault_secret.org, azurerm_key_vault.copyorg ] }

enter image description here

Also check https://zimmergren.net/backup-azure-key-vault-secrets-keys-certificates/

kavyaS
  • 8,026
  • 1
  • 7
  • 19
  • do you know if there's a way to use only one keyvault secret for all the disks in Vms during encryption so that we do not have to create a new secret in the target region everytime we have a new VM that need to enable the ASR? So for example for keyvault key, we have this configured already: Source region West Europe: Keyvault : we-key-prod-01 Keyvault key : we-enc-key-prod-01 Target Region North Europe: Keyvault: we-key-prod-01-asr Keyvault key: we-enc-key-prod-01 How about for the keyvault secret, is there's a way to create it in advance and specify it during the encryption of Disk? – Marijane May 17 '23 at 07:16