Skip to main content

Replicate VM to Azure Using Veeam

VSCODE,powershell,azure

Veeam Replicate to Azure with PowerShell & API.

I’ve done a previous post on restoring VMs into azure using PowerShell

Here: http://www.mritsurgeon.co.za/2020/02/restoring-multiple-vms-to-azure-part-2.html

I wanted to further enhance this with Azure so that a scheduled script would remove older VM and restore newer VM, I additionally wanted there to be a revert option to older version of the VM through a VM snapshot.

 How It Works:

First, we Create a Scale out Backup repository to land onsite backups, within the scale out backup repository you connect a capacity tier to Azure Object (BLOB)

Veeam copies all onsite backups into blob through a copy policy in SOBR

We then deploy a Community Veeam backup & replication Instance in Azure, this instance we attach the Capacity tier as an Object repository & we import backups.

** Why 2 backup servers? If we run the script locally on on-prem backup server, even if the script selects Object storage backup restore point Veeam tries to use local copy, by using community Instance it has no local copies and only holds Restore points in Object.

Next , we deploy Veeam backup for Azure ( VBA ) instance in azure , This we will use to create VM snapshots of the azure instance before we remove the instance and replace with image from latest backup, I did look at using native Azure but with VBA we can easily create a policy for all VMs that we will overwrite and we can trigger that policy via API , The policy will also manage the retention as well as reverting the VMs back to a previous image.

Lastly you need to initiate the first restore to azure using Veeam Direct restore similar to this blog Post's script Here: http://www.mritsurgeon.co.za/2020/02/restoring-multiple-vms-to-azure-part-2.html

Diagram Replication to Azure with veeam
Requirements:

  • ·         Veeam Backup Server On premise
  • ·         SOBR (Scale out Backup repository)
  • ·         Capacity extent (Azure Blob)
  • ·         Veeam backup community edition in azure
  • ·         Veeam Backup for azure (VBA) in azure
  • ·         Azure Subscription & Resource Group
  • ·         Azure PowerShell Module

Lets Begin:

Firstly, do your initial Restores into azure , here is a post I did on this, if you need more information.

Here: http://www.mritsurgeon.co.za/2020/02/restoring-multiple-vms-to-azure-part-2.html

Run this from Community edition VBR instance in Azure for best Performance & Throughput.

Here is some of the main script for the restore process:

#Set azure Variables

$accountCloud = Get-VBRAzureAccount -Type ResourceManager -Name "yourname@yourcompany.com"

$subscription = Get-VBRAzureSubscription -Account $accountCloud -Name "your subscription"

$storageaccount = Get-VBRAzureStorageAccount -Subscription $subscription -Name "africasouth"

$location = Get-VBRAzureLocation -Subscription $subscription -Name "southafricanorth"

$vmsizeSMALL = Get-VBRAzureVMSize -Subscription $subscription -Location $location -Name Standard_A2_v2

#$vmsizeMEDIUM = Get-VBRAzureVMSize -Subscription $subscription -Location $location -Name Standard_A4_v2

#$vmsizeLARGE = Get-VBRAzureVMSize -Subscription $subscription -Location $location -Name Standard_A8_v2

$network = Get-VBRAzureVirtualNetwork -Subscription $subscription -Name "Africa-vnet"

$subnet = Get-VBRAzureVirtualNetworkSubnet -Network $network -Name "default"

$resourcegroup = Get-VBRAzureResourceGroup -Subscription $subscription -Name "Africa"

$nsg = Get-VBRAzureNetworkSecurityGroup -Subscription $subscription -Name "vbrafrica*"

You can change the VM sizes assigned to $VMSizes

Next :

#begin new restore

$restorepoint = Get-VBRBackup -Name "vmware" | Get-VBRRestorePoint -Name "win2azure" | where {$_.FindStorage().ExternalContentMode -eq 'External'} | Select -last 1

Start-VBRVMRestoreToAzure -RestorePoint $restorepoint -Subscription $subscription -StorageAccount $storageaccount -StorageType Managed -VmSize $vmsizeSMALL -VirtualNetwork $network -VirtualSubnet $subnet -ResourceGroup $resourcegroup -NetworkSecurityGroup $nsg -VmName "win-replica" -Reason "TESTING MY NEW SCRIPT" -ShutdownVM

In VBR console you should see restore process to Azure, once completed

Login to Veeam Backup for Azure, if not deployed follow this VBA guide:

https://helpcenter.veeam.com/docs/vbazure/guide/installing_product.html?ver=10

Create a policy for the Restored VMs, I chose only to use snapshots and set retention to only keep X number of Snapshots, these snapshots we can use to revert VM if script fails or anything goes wrong.

Veeam backup for azure

Retention settings on snapshots

Veeam Backup for azure snapshots

Once this is done you need to retrieve IP / Hostname for VBA instance so we can call API.

First step is to Get Auth token from VBA using your Username & Password for VBA login.

# Auth Get Token

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"

$headers.Add("Authorization", "Bearer")

$headers.Add("Content-Type", "application/x-www-form-urlencoded")

add-type @"

    using System.Net;

    using System.Security.Cryptography.X509Certificates;

    public class TrustAllCertsPolicy : ICertificatePolicy {

        public bool CheckValidationResult(

            ServicePoint srvPoint, X509Certificate certificate,

            WebRequest request, int certificateProblem) {

            return true;

        }

    }

"@

[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy

$body = "grant_type=password&username=(VBA USERNAME)&password=(VBA PASSWORD)"

$response = Invoke-RestMethod 'https://(VBA IP OR HOSTNAME)/api/oauth2/token' -Method 'POST' -Headers $headers -Body $body

$response | ConvertTo-Json

$Access_token = $response.access_token

Once this returns successfully you have Access token assigned to variable $Access_token

We will use this variable to Auth other API requests.

Next we need to identify the Policy ID in VBA that we will start before we remove VMs from azure, this is the one we created in previous steps as shown in screenshots.

In the below screenshot I used Postman to retrieve Policies and URI that I will call to start policy.

Postman & Veeam API


Now that we have policy the we can Start the policy before we remove VMs to replace with newest backup image.

#Start Backup Policiy

$headerspol = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"

$headerspol.Add("Authorization", "Bearer $Access_token " )

$responsepol = Invoke-RestMethod 'https://(VBA IP OR HOSTNAME)/api/v1/policies/(YOUR VBA POLICY ID)/start' -Method 'POST' -Headers $headerspol -Body $bodypol

$responsepol | ConvertTo-Json

$Jobsession = $responsepol._links.self.href

Here I started the policy via API and assigned the Policy session to a variable which will be called in next part of the script $Jobsession

We can see in VBA the policy running at this point

Veeam backup for Azure

Next Api call uses the $jobsession to check on its status to make sure its completed before removing VMs.

#Gets Session status

$headersSes = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"

$headersSes.Add("Authorization", "Bearer $Access_token " )

$responseSes = Invoke-RestMethod -Uri $Jobsession -Method 'GET' -Headers $headersSes

$responseSes | ConvertTo-Json

$status = $responseSes.status

Write-Host " Policy running , pause for 2 min "

$colors = @("Green","Cyan","Red","Magenta","Yellow","White")

for (($x=''),($fgcolor = $colors | Get-Random) ;$x.length -le 30;($x=$x+'x'),($fgcolor = $colors | Get-Random)){

    Write-Host $x -ForegroundColor $fgcolor

}

Start-Sleep -s 120

#Recheck session

$headersSes = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"

$headersSes.Add("Authorization", "Bearer $Access_token " )

$responseSes = Invoke-RestMethod -Uri $Jobsession -Method 'GET' -Headers $headersSes

$responseSes | ConvertTo-Json

$status = $responseSes.status

if ($status -eq "Running") {

write-host "Job Still Busy"

$colors = @("Green","Cyan","Red","Magenta","Yellow","White")

for (($x=''),($fgcolor = $colors | Get-Random) ;$x.length -le 30;($x=$x+'x'),($fgcolor = $colors | Get-Random)){

    Write-Host $x -ForegroundColor $fgcolor

}

Write-Host "Waiting for another 2min "

Start-Sleep -s 120

}

Else {write-host "job completed"}

Write-Host " New Replica VM Processing "

Uses an If statement to pause script if Job is still running, after marked as successful script will then move onto Azure PowerShell module to remove Azure Objects.

In the screenshot below you can see the objects that need to be removed , The reason for removing these objects is that Veeam will throw an error if VM already exists , so we will remove them and recreate them from newest image in backup, NSG will be reused so not necessary to be removed.

Azure VM objects

So once again we set Variables for Azure Before we call Az PowerShell .

If you don’t have AZ PowerShell module you can install this with the following command:

 

 Install-Module -Name Az -AllowClobber -Force

 

#Set azure Variables

$User = "yourname@yourcompany.com"

$PWord = ConvertTo-SecureString -String "*******" -AsPlainText -Force

$azCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $User, $PWord

$accountCloud = Get-VBRAzureAccount -Type ResourceManager -Name "yourname@yourcompany.com"

$subscription = Get-VBRAzureSubscription -Account $accountCloud -Name "your subscription"

$storageaccount = Get-VBRAzureStorageAccount -Subscription $subscription -Name "africasouth"

$location = Get-VBRAzureLocation -Subscription $subscription -Name "southafricanorth"

$vmsizeSMALL = Get-VBRAzureVMSize -Subscription $subscription -Location $location -Name Standard_A2_v2

#$vmsizeMEDIUM = Get-VBRAzureVMSize -Subscription $subscription -Location $location -Name Standard_A4_v2

#$vmsizeLARGE = Get-VBRAzureVMSize -Subscription $subscription -Location $location -Name Standard_A8_v2

$network = Get-VBRAzureVirtualNetwork -Subscription $subscription -Name "Africa-vnet"

$subnet = Get-VBRAzureVirtualNetworkSubnet -Network $network -Name "default"

$resourcegroup = Get-VBRAzureResourceGroup -Subscription $subscription -Name "Africa"

$nsg = Get-VBRAzureNetworkSecurityGroup -Subscription $subscription -Name "vbrafrica*"

Next, we connect to Azure and Remove Objects, things like Public IP if not allocated don’t need to be removed as they don’t exist.

#Connect to azure

Connect-AzAccount -Credential $azCredential

$VMrep = Get-AzVM -ResourceGroupName $resourcegroup -Name "win-replica"

#Stop and remove Azure objects

Stop-AzVM -ResourceGroupName $resourcegroup -Name $VMrep.Name -Force

Remove-AzVM -ResourceGroupName $resourcegroup -Name $VMrep.Name -Force

$NetInt = Get-AzNetworkInterface -ResourceGroupName $resourcegroup -Name "win-replica*"

Remove-AzNetworkInterface -ResourceGroupName $resourcegroup -Name $Netint.Name -Force

$repdisk = Get-AzDisk -ResourceGroupName $resourcegroup -Name "win-replica*"

$PIP = Get-AzPublicIpAddress -ResourceGroupName $resourcegroup -Name "win-replica*"

#Remove-AzPublicIpAddress -ResourceGroupName $resourcegroup -Name $pip.Name -Force

Remove-AzDisk -ResourceGroupName $resourcegroup -Name $repdisk.Name -force

Now that the Objects are removed the last part of the Script is to restore the latest Image from backup.

#connect to veeam

Add-PSSnapin VeeamPSSnapin

Connect-VBRServer -Server "YOUR VEEAM SERVER HOSTNAME"

#begin new restore

$restorepoint = Get-VBRBackup -Name "vmware" | Get-VBRRestorePoint -Name "win2azure" | where {$_.FindStorage().ExternalContentMode -eq 'External'} | Select -last 1

Start-VBRVMRestoreToAzure -RestorePoint $restorepoint -Subscription $subscription -StorageAccount $storageaccount -StorageType Managed -VmSize $vmsizeSMALL -VirtualNetwork $network -VirtualSubnet $subnet -ResourceGroup $resourcegroup -NetworkSecurityGroup $nsg -VmName "win-replica" -Reason "TESTING MY NEW SCRIPT"

ShutdownVM

You can observe the restore Process in Veeam & potentially write a script to report on Replication scenario

Restore to Azure

VM will be powered off once restore is completed.

If Something was to go wrong, we can go back to VBA and restore the Snapshot to overwrite the VM, I tested to make sure this would work see the below screenshots.

 

Restore with Veeam backup for azure


Veeam backup for azure Restore session


So here is the full script and you can just make changes by adding credentials, policy ID and VM names where necessary.

This script should be run from community edition VBR in azure & you can schedule the script to run using 3rdparty tools or windows Task Scheduler.

Hope this was helpful, please comment & share

Thanks for taking the time to read.

 The Full SCRIPT :


Comments