Multi-region deployments in Microsoft Azure are often part of a highly-available Citrix Cloud DaaS implementation. One of the challenges associated with this style of deployment is ensuring that you have a replica of your images available to spin up catalogs based on a local image source rather than relying on MCS trying to push your image regionally (which can be done but is mighty slow and failure can result in lengthy catalog update processes).
Yes, there is of course the Azure Image Gallery (now the Azure Compute Gallery) but this doesn’t offer the flexibility or controls that I want specifically for Citrix deployments currently.
As a principal, I always use Azure snapshots to update Machine Catalogs. I have a small script CreateOSSnapshot here which I used to ensure consistent naming.
DifferentSubDifferentRegionwill replicate Snapshots from one region to another region in a different subscription. This is the default mode of operations
DifferentSubSameRegionwill replicate Snapshots from one region to another region in the same subscription
SameSubDifferentRegionwill replicate Snapshots to the same region in different subscription
The script has the following modes of operation and filtering controls:
Tag Filtering. Only replicate snapshots with a specific tag (Tag:
Sync. This mode will compare the source and target Resource Groups to keep them in sync. If you delete a snapshot in the source, it will be removed from the target. The source Resource Group is always authoritative
To implement the solution, you simply need an Azure Automation Account using a System Assigned Managed Identity.
The managed identity must have contributor permissions on the source and target Resource Groups as the script will handle locks on existing Snapshots, Storage Account creation and deletion when going cross-region and creation/deletion of snapshots in the target Resource Group when in Sync mode
Update the Azure Modules on the runbook to make sure they are the latest (PowerShell 7.1 please)
Add a new runbook with PowerShell 7.1
Set your logging levels as below:
Make sure you have permissions on both the source and target Resource Groups as above
Add the code, and set your variables either statically within the script, or within the schedule if you are doing multiple jobs and sync cycles to different regions. Either is fine.
SourceSubscriptionIDThe source subscription ID of where your snapshots live
TargetSubscriptionIDIf moving cross subscription, this is the target Subscription ID for where your snapshots will sync to
SourceResourceGroupThe source Resource Group (name) of where your snapshots live
TargetResourceGroupThe target Resource Group (name) for where your snapshots will sync to
TargetRegionIf moving region, the target region for your snapshots
SnapshotNameIndividual snapshot name to sync. Cannot be used with
ModeOffers 3 models of operation
SyncSets the flag to compare source and destination Resource Group Snapshots. This is a sync job. If a deletion occurs in the source, it will be mirrored in the target. Values:
UseTagFilteringThe recommended model for
Sync. Requires setting a tag on snapshots in the source which are targeted for sync to the target. Ignores all other snaps
isAzureRunbookThe designed operational model for this runbook (Defaults to
LogPathLogpath output for all operations – valid when not running as a runbook primarily
LogRolloverNumber of days before logfiles are rolled over. Default is
Assign a schedule and off you go. All output will be pushed to the console so you can review it appropriately.
That’s it. Now you have a zero-touch synchronisation solution which ensures local copies of your snapshots ready for quick and efficient catalog creations. Easy.
You can download the ReplicateAzureSnapshot script here. Feel free to consume and adapt as you see fit.