Edit

Share via


Manual backup and recovery of guest state protection keys for Trusted launch Azure Local VMs enabled by Azure Arc

Applies to: Azure Local 2311.2 and later

This article describes how to manually back up and restore guest state protection keys for Trusted launch Azure Local virtual machines (VMs) enabled by Azure Arc.

  • For Azure Local release 2505 and later: Back up and restore Azure Local VM guest state protection keys to and from a file system folder.

  • For Azure Local releases prior to 2505: Back up and restore Azure Local VM guest state protection keys to and from a key vault in another Azure Local instance.

This section applies to Azure local release 2505 and later.

For back up, VM guest state protection keys are copied from the on-premises key vault of your Azure Local instance to a folder that is backed up periodically. The VM guest state protection keys stored inside that folder are in an encrypted form.

For restore, VM guest state protection keys are restored from a folder containing the backup copy to the key vault of an Azure Local instance where the VMs need to be restored.

Back up keys

The steps below involve copying VM guest state protection keys from the local key vault of your Azure Local instance to a folder that is backed up periodically.

  1. On a secure computer using PowerShell 7, generate a wrapping key of size 2048:

    $rsa = [System.Security.Cryptography.RSA]::Create(2048) 
    
    $privateKeyPem = $rsa.ExportPkcs8PrivateKeyPem() 
    
    $privateKeyPem | Out-File -FilePath .\private.pem 
    
    $publicKeyPem = $rsa.ExportRSAPublicKeyPem() 
    
    $publicKeyPem | Out-File -FilePath .\public.pem 
    
  2. Make a note of the wrapping key as you need it later.

  3. Copy the .\public.pem file to your Azure Local instance.

  4. Copy VM guest state protection keys from the local key vault of your Azure Local instance to a folder that is backed up periodically:

    1. Download the TvmBackupUtils.psm1 script on GitHub to your Azure Local instance.

    2. Run the following:

      import-module .\TvmBackupUtils.psm1 -force
      
      Backup-TVMKeys -WrappingKeyPath <path to public.pem> -BackupRootPath <path to backup root folder where the timestamped backup folder is stored>
      

      Here's a sample output after running this command:

      Backing up TVM Vault keys to .\<backup root folder>\20250722192116
      Backing up key 11111111-1111-1111-1111-111111111111 to AES folder
      Backing up key 7fb16fe7-00a0-476f-92b3-ccb98fd9525a to AES folder
      Backing up key AzureStackTvmAKRootKey to RSA folder
      
  5. Make note of the timestamped backup folder created under the backup root folder. You need this later during recovery. For example, backup folder named "2025-06-12-20-53-55" with the format "yyyy-MM-dd-HH-mm-ss".

Restore keys

The steps below involve restoring VM guest state protection keys from a folder containing the backup copy to the key vault of an Azure Local instance where the VMs need to be restored.

  1. Copy both private and public key files for the wrapping key that you created previously to the Azure Local instance.

  2. Copy the timestamped backup folder to the Azure Local instance. Pick the folder under the backup root folder with the latest timestamp as that folder will have the most recent copy. Don't modify the backup folder.

  3. Import the wrapping key that you created previously to the Azure Local instance:

    1. Download the TvmBackupUtils.psm1 script on GitHub to your Azure Local instance.

    2. Run the following commands.

      Note

      Make sure to create a unique name for the WrappingKeyName. Otherwise, this causes a failure during import:

      Import-Module .\TvmBackupUtils.psm1 -force 
      
      Import-TvmWrappingKeyFromPem -KeyName <WrappingKeyName> -PublicKeyPath <path to public.pem> -PrivateKeyPath <path to private.pem> -KeySize 2048
      

      Here's sample output:

      Generating import JSON for key <WrappingKeyName> at temporary ___location C:\Users\HCIDeploymentUser\AppData\Local\Temp\tmpD383.tmp... 
      Importing key <WrappingKeyName> into the vault...
      Key <WrappingKeyName> successfully imported into the vault.
      Temporary file C:\Users\HCIDeploymentUser\AppData\Local\Temp\tmpD383.tmp has been cleaned up.
      
  4. Do this step only if you're restoring the VM to the same Azure Local instance where the VM resided before failure. Delete AzureStackTvmAKRootKey as follows:

    Remove-MocKey -name  AzureStackTvmAKRootKey -group AzureStackHostAttestation -keyvaultName AzureStackTvmKeyVault
    
  5. Restore the keys from backup:

    Import-TVMKeys -WrappingKeyName <WrappingKeyName> -BackupPath <path to timestamped backup folder>
    

    Here's sample output:

    Importing TVM  keys from .\tvm_keys_backup_root\20250722192116\
    
    Importing key 11111111-1111-1111-1111-111111111111 with size 256 from AES folder path = .\tvm_keys_backup_root\20250722192116\AES\11111111-1111-1111-1111-111111111111_256.json
    
    Importing key 7fb16fe7-00a0-476f-92b3-ccb98fd9525a with size 256 from AES folder path = .\tvm_keys_backup_root\20250722192116\AES\7fb16fe7-00a0-476f-92b3-ccb98fd9525a_256.json
    
    Importing key AzureStackTvmAKRootKey with size 4096 from RSA folder path = .\tvm_keys_backup_root\20250722192116\RSA\AzureStackTvmAKRootKey_4096.json
    

    If the local key vault of the Azure Local instance already has a VM guest state protection key with the same name or already has an AzureStackTvmAKRootKey, you receive an InvalidVersion error for that key. You can ignore this, as the key is already in the key vault.

    Here's sample output showing this error:

    Importing TVM  keys from .\tvm_keys_backup_root\20250722192116\
    Importing key 11111111-1111-1111-1111-111111111111 with size 256 from AES folder path = .\tvm_keys_backup_root\20250722192116\AES\11111111-1111-1111-1111-111111111111_256.json
    Import-TVMKeys : Error Importing Key: C:\Program Files\AksHci\mocctl.exe --cloudFqdn
    s-cluster.v.masd.stbtest.microsoft.com  security keyvault key import --group "AzureStackHostAttestation" --key-size
    "256" --vault-name "AzureStackTvmKeyVault" --key-type "AES" --key-file-path
    ".\tvm_keys_backup_root\20250722192116\AES\11111111-1111-1111-1111-111111111111_256.json" --name
    "11111111-1111-1111-1111-111111111111" --wrapping-key-name "WrappingKey" System.Collections.Hashtable.generic_non_zero
    1 [Error: Keys Import failed:  Type[Key] Vault[AzureStackTvmKeyVault] Name[11111111-1111-1111-1111-111111111111]:
    InvalidVersion]
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Import-TVMKeys
    
    Importing key 7fb16fe7-00a0-476f-92b3-ccb98fd9525a with size 256 from AES folder path = .\tvm_keys_backup_root\20250722192116\AES\7fb16fe7-00a0-476f-92b3-ccb98fd9525a_256.json
    Import-TVMKeys : Error Importing Key: C:\Program Files\AksHci\mocctl.exe --cloudFqdn
    s-cluster.v.masd.stbtest.microsoft.com  security keyvault key import --group "AzureStackHostAttestation" --key-size
    "256" --vault-name "AzureStackTvmKeyVault" --key-type "AES" --key-file-path
    ".\tvm_keys_backup_root\20250722192116\AES\7fb16fe7-00a0-476f-92b3-ccb98fd9525a_256.json" --name
    "7fb16fe7-00a0-476f-92b3-ccb98fd9525a" --wrapping-key-name "WrappingKey" System.Collections.Hashtable.generic_non_zero
    1 [Error: Keys Import failed:  Type[Key] Vault[AzureStackTvmKeyVault] Name[7fb16fe7-00a0-476f-92b3-ccb98fd9525a]:
    InvalidVersion]
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Import-TVMKeys
    
    Importing key AzureStackTvmAKRootKey with size 4096 from RSA folder path = .\tvm_keys_backup_root\20250722192116\RSA\AzureStackTvmAKRootKey_4096.json
    Import-TVMKeys : Error Importing Key: C:\Program Files\AksHci\mocctl.exe --cloudFqdn
    s-cluster.v.masd.stbtest.microsoft.com  security keyvault key import --group "AzureStackHostAttestation" --key-size
    "4096" --vault-name "AzureStackTvmKeyVault" --key-type "RSA" --key-file-path
    ".\tvm_keys_backup_root\20250722192116\RSA\AzureStackTvmAKRootKey_4096.json" --name "AzureStackTvmAKRootKey"
    --wrapping-key-name "WrappingKey" System.Collections.Hashtable.generic_non_zero 1 [Error: Keys Import failed:
    Type[Key] Vault[AzureStackTvmKeyVault] Name[AzureStackTvmAKRootKey]: InvalidVersion]
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Import-TVMKeys
    
  6. Clean up files and keys:

    1. Delete both public.pem and private.pem files from the Azure Local instance.

      Important

      Remove the wrapping key from the key vault of the Azure Local instance using Remove-MocKey. This helps avoid collisions later.

      Remove-MocKey -name WrappingKeyName -group AzureStackHostAttestation -keyvaultName AzureStackTvmKeyVault
      

Next steps