Skip to content

Instantly share code, notes, and snippets.

@archmangler
Last active October 3, 2018 00:16
Show Gist options
  • Save archmangler/3ca8a5d3e7cf7e4cc7e2e68ff903be62 to your computer and use it in GitHub Desktop.
Save archmangler/3ca8a5d3e7cf7e4cc7e2e68ff903be62 to your computer and use it in GitHub Desktop.
Terraform RSV Enabled Virtual Machine

AzureRM Recovery Services Vault Lab Notes

Question: How to enable AzureRM RSV for a virtual machine at deployment time?

  1. integrating arm template with linux vm terraform
  • we do this so we can include the rsv parameters (i.e "enable backups")
 azurerm_template_deployment 

... but it looks like it's not Supported:

  1. Support for recovery services in terraform is under development:
  1. So we use powershell to register a VM to a vault:

PowerShell AzureRM.NetCore does not yet appear to support this on linux (even in the lates release: https://github.com/PowerShell/PowerShell/releases):

a) https://docs.microsoft.com/en-us/powershell/azure/install-azurermps-maclinux?view=azurermps-6.8.1 b) PowerShell/PowerShell#7848

If it did, the following procedure could be used:

  • Enable protection on a "classic" virtual machine (as opposed to BEK and KEK encrypted VMs ??)

MS documentation is typically obscure (while giving the illusion of completeness):

$pol = Get-AzureRmRecoveryServicesBackupProtectionPolicy -Name "NewPolicy" Enable-AzureRmRecoveryServicesBackupProtection -Policy $pol -Name "V1VM" -ServiceName "ServiceName1"

Some random blog on the internet clarifies:

  • Test sequence for developing the required Powershell (this can be a script template called by terraform's local-exec provider):

Step 1: Login

Login-AzureRmAccount

Step 2: First time registratration of recovery services:

Register-AzureRmResourceProvider-ProviderNamespace "Microsoft.RecoveryServices"

Step 3: Create a recovery services vault:

 New-AzureRmRecoveryServicesVault-ResourceGroupName "vmRG" -Name "myVMRecoveryServicesVault" -Location "WestEurope"

Step 4: Switch/Set vault context

Get-AzureRmRecoveryServicesVault-Name “myRecoveryServicesVault” | Set-AzureRmRecoveryServicesVaultContext

Step 5: Get policy details (This will be the default policy)

#Create a variable $policy  to store the policy details.
$policy = Get-AzureRmRecoveryServicesBackupProtectionPolicy-Name "DefaultPolicy"

Step 6: Enable the backup on a VM in a resourceGroup using policyd $policy:

Enable-AzureRmRecoveryServicesBackupProtection-ResourceGroupName "vmRG" -Name "myPersonalVM" -Policy $policy

Testing

  • inelegant authentication method (interactive):
gmonkey@tfvm:~/Ship/tf4te-book/examples/azure_server_instance$ pwsh ./test.ps1
WARNING: To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code HZGV2N87X to authenticate.



  • need to install the module first:

pwsh> Install-Module -Name AzureRM.RecoveryServices

Issues:

  • Issue #1
You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the
Set-PSRepository cmdlet. Are you sure you want to install the modules from 'PSGallery'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): A
PackageManagement\Install-Package : The member 'TypesToProcess' in the module manifest is not valid: Cannot find path '/tmp/399344315/Azure.Storage.4.5.0/.\Microsoft.WindowsAzure.Commands.Storage.Types.ps1xml' because it does not exist.. Verify that a valid value is specified for this field in the '/tmp/399344315/Azure.Storage.4.5.0/Azure.Storage.psd1' file.                                                                                                            At /opt/microsoft/powershell/6/Modules/PowerShellGet/PSModule.psm1:9491 char:21                                                                             + ...          $null = PackageManagement\Install-Package @PSBoundParameters                                                                                 +                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~                                                                                 + CategoryInfo          : ResourceUnavailable: (/tmp/399344315/...re.Storage.psd1:String) [Install-Package], Exception                                      + FullyQualifiedErrorId : Modules_InvalidManifest,Microsoft.PowerShell.Commands.TestModuleManifestCommand,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage

Enable-AzureRmRecoveryServicesBackupProtection : The term 'Enable-AzureRmRecoveryServicesBackupProtection' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At /home/gmonkey/Ship/tf4te-book/examples/azure_server_instance/test.ps1:21 char:1
+ Enable-AzureRmRecoveryServicesBackupProtection -ResourceGroupName "vm ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (Enable-AzureRmR...ackupProtection:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException

Solution: Install AzureRM.RecoveryServices.Backup module ...

PS /home/gmonkey/Ship/tf4te-book/examples/azure_server_instance> Install-Module AzureRM.RecoveryServices.Backup -AllowClobber -Scope CurrentUser

Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the
Set-PSRepository cmdlet. Are you sure you want to install the modules from 'PSGallery'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): A
PS /home/gmonkey/Ship/> Get-AzureRmRecoveryServicesVault -Name myRecoveryServicesVault | Set-AzureRmRecoveryServicesVaultContext                                                                                                                                               Get-AzureRmRecoveryServicesVault : The term 'Get-AzureRmRecoveryServicesVault' is not recognized as the name of a cmdlet, function, script file, or operable program.
Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ Get-AzureRmRecoveryServicesVault -Name myRecoveryServicesVault | Set- ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (Get-AzureRmRecoveryServicesVault:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
  • Solution: None as yet available in the debian package system:

Reference: https://docs.microsoft.com/en-us/powershell/azure/install-azurermps-maclinux?view=azurermps-6.8.1

PS /home/gmonkey> Install-Module AzureRM.RecoveryServices -AllowClobber -Scope CurrentUser

Untrusted repository
You are installing the modules from an untrusted repository. If you trust this repository, change its InstallationPolicy value by running the
Set-PSRepository cmdlet. Are you sure you want to install the modules from 'PSGallery'?
[Y] Yes  [A] Yes to All  [N] No  [L] No to All  [S] Suspend  [?] Help (default is "N"): A
PS /home/gmonkey>
  • Solution: New Az module replaces the old:

Azure/azure-powershell#6975

Issue #4:

Confirm
Provided resource group already exists. Are you sure you want to update it?
[Y] Yes  [N] No  [S] Suspend  [?] Help (default is "Y"): Y

ResourceGroupName : vmRG
Location          : westeurope
ProvisioningState : Succeeded
Tags              :
TagsTable         :
ResourceId        : /subscriptions/45dc5356-34fc-4e8c-8b1e-0992f34f7b2d/resourceGroups/vmRG


Name              : myVMRecoveryServicesVault
ID                : /subscriptions/45dc5356-34fc-4e8c-8b1e-0992f34f7b2d/resourceGroups/vmRG/providers/Microsoft.RecoveryServices/vaults/myVMRecoveryServicesVault
Type              : Microsoft.RecoveryServices/vaults
Location          : westeurope
ResourceGroupName : vmRG
SubscriptionId    : 45dc5356-34fc-4e8c-8b1e-0992f34f7b2d
Properties        : Microsoft.Azure.Commands.RecoveryServices.ARSVaultProperties

Get-AzureRmRecoveryServicesBackupProtectionPolicy : Set vault context first using cmdlet Set-AzureRmRecoveryServicesVaultContext
At /home/gmonkey/Ship/tf4te-book/examples/recovery-vault/test.ps1:21 char:11
+ $policy = Get-AzureRmRecoveryServicesBackupProtectionPolicy -Name "De ...
+           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Get-AzureRmReco...rotectionPolicy], ArgumentException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.GetAzureRmRecoveryServicesBackupProtectionPolicy

Enable-AzureRmRecoveryServicesBackupProtection : Cannot validate argument on parameter 'Policy'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again.
At /home/gmonkey/Ship/tf4te-book/examples/recovery-vault/test.ps1:24 char:100
+ ... rotection -ResourceGroupName "vmRG" -Name "tfvmex-vm" -Policy $policy
+                                                                   ~~~~~~~
+ CategoryInfo          : InvalidData: (:) [Enable-AzureRmR...ackupProtection], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.EnableAzureRmRecoveryServicesBackupProtection

And more issues:

PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault> echo $vault


Name              : myVMRecoveryServicesVault2
ID                : /subscriptions/45dc5356-34fc-4e8c-8b1e-0992f34f7b2d/resourceGroups/vmRG/providers/Microsoft.RecoveryServices/vaults/myVMRecoveryServicesVault2
Type              : Microsoft.RecoveryServices/vaults
Location          : westeurope
ResourceGroupName : vmRG
SubscriptionId    : 45dc5356-34fc-4e8c-8b1e-0992f34f7b2d
Properties        : Microsoft.Azure.Commands.RecoveryServices.ARSVaultProperties



PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault>
PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault>
PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault> Set-AzureRmRecoveryServicesVaultContext -Vault $vault
PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault> $policy = Get-AzureRmRecoveryServicesBackupProtectionPolicy -Name "DefaultPolicy"
PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault> echo $policy

Name                 WorkloadType       BackupManagementType BackupTime                DaysOfWeek
----                 ------------       -------------------- ----------                ----------
DefaultPolicy        AzureVM            AzureVM              10/3/18 10:00:00 AM


PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault>
PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault>
PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault>
PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault> Enable-AzureRmRecoveryServicesBackupProtection -ResourceGroupName "vmRG" -Name "tfvmex-vm" -Policy $policy

PS /home/gmonkey/Ship/tf4te-book/examples/recovery-vault> Enable-AzureRmRecoveryServicesBackupProtection -ResourceGroupName "vmRG" -Name "tfvmex-vm" -Policy $policy
Enable-AzureRmRecoveryServicesBackupProtection : The specified Azure Virtual Machine Not Found. Possible causes are
1. VM does not exist
2. The VM name or the Service name needs to be case sensitive
3. VM is already Protected with same or other Vault. Please Unprotect VM first and then try to protect it again.
Please contact Microsoft for further assistance.
At line:1 char:1
+ Enable-AzureRmRecoveryServicesBackupProtection -ResourceGroupName "vm ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Enable-AzureRmR...ackupProtection], Exception
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.EnableAzureRmRecoveryServicesBackupProtection

Enable-AzureRmRecoveryServicesBackupProtection : The specified Azure Virtual Machine Not Found. Possible causes are
1. VM does not exist
2. The VM name or the Service name needs to be case sensitive
3. VM is already Protected with same or other Vault. Please Unprotect VM first and then try to protect it again.
Please contact Microsoft for further assistance.
At line:1 char:1
+ Enable-AzureRmRecoveryServicesBackupProtection -ResourceGroupName "vm ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [Enable-AzureRmR...ackupProtection], Exception
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.EnableAzureRmRecoveryServicesBackupProtection

Enable-AzureRmRecoveryServicesBackupProtection : Object reference not set to an instance of an object.
At line:1 char:1
+ Enable-AzureRmRecoveryServicesBackupProtection -ResourceGroupName "vm ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : NotSpecified: (:) [Enable-AzureRmR...ackupProtection], NullReferenceException
+ FullyQualifiedErrorId : Microsoft.Azure.Commands.RecoveryServices.Backup.Cmdlets.EnableAzureRmRecoveryServicesBackupProtection

  • Azure CLI enable Virtual Machine for backups to RSV

Ref: https://docs.microsoft.com/en-us/azure/backup/quick-backup-vm-cli

"Create a protection policy to define: when a backup job runs, and how long the recovery points are stored. The default protection policy runs a backup job each day and retains recovery points for 30 days. You can use these default policy values to quickly protect your VM. To enable backup protection for a VM, use az backup protection enable-for-vm. Specify the resource group and VM to protect, then the policy to use:"

az backup protection enable-for-vm \
    --resource-group myResourceGroup \
    --vault-name myRecoveryServicesVault \
    --vm myVM \
    --policy-name DefaultPolicy

Testing Enablement of RSV for Virtual Machines

... Finally we get to this part ...

  • Setup a RSV
  • Run the script
  • Evaluate Results
  • Improve the script
  • Integrate into Terraform VM deployment module (local-exec)
  • Remove any technical debt up-front



@archmangler
Copy link
Author

You'll need to test the effect of this on terraform refresh, apply and destroy.
If adding this configuration after deployment of the VM results in the tfstate getting out of sync then we have to include an on-destroy execution which de-registers the VM from the recovery service vault.

@archmangler
Copy link
Author

Solution to support issue: Azure/azure-powershell#6975

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment