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
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.
Retention settings on 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.
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
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.
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
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.
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
Post a Comment
Leave your Thoughts & Comments , and I'll reply as soon as possible.
Thank you for you views in Advance.