Azure files is a great method for phasing out your traditional file servers. It provides great scalability and the end-user experience remains the same. For the IT department it means there is zero or almost no maintenance necessary.
In order to still provide features as ‘previous versions’ and a solid backup method, Azure has it’s own backup services in place. You can manually take a snapshot of a Azure File Share if needed. You can also protect the fileshare via Recovery Services Vault. Which is basically the same, because Recovery Services Vault also creates a snapshot.
But in order to have the ‘previous versions’ within you Azure Files environment, you need to create a file share snapshot every X hours/days. We have created a DevOps release pipeline to do so. The release pipeline is running on an hourly-schedule to have the most flexible end-user experience.
The release pipeline kicks off a PowerShell script to create a new snapshot and remove snapshots older then x days. To keep things clean ;).
Creating the snapshot is simple by just filling an variable with it’s sharename and context. Creating the snapshot is done via the useage of “CloudFileShare”. Microsoft reference here.
$share = Get-AzStorageShare -Context $storageAcct.Context -Name $shareName
$snapshot = $share.CloudFileShare.Snapshot()
So far so good, the tricky part is in the deletion of the snapshots older than for example 7 days. Because we have two snapshots methods in this case:
- Azure Recovery Services Vault with a file share backup. With a backup policy attached for retention stuff.
- Creation of snapshots on the file shares via de DevOps release pipeline in order to provide the user’s ‘previous versions’.
Within the DevOps script we, earlier, removed all snapshots older then 7 days. So far so good. But if we want to restore a fileshare from a restore point for example january 2021 it fails. And it is failing because the snapshot where Azure Recovery Services Vault is pointing to, is gone. Our script removed it because it does not sees the difference between a snapshot created by Azure DevOps release pipeline and a snapshot created by Azure Recovery Services Vault.
That’s tricky!
Within Azure, the ability to manage Azure File shares snapshots are very limited with PowerShell. You cannot give the snapshot a custom name or comment. The main difference, as you can see in the screenshot is the “Initiator” column. When the Azure DevOps pipeline creates the snapshot it is marked as “manual”. So the ‘remove snapshots’ part within our script has to be affected on the “Manual” snapshots.
Removal is easily done via:
Remove-AzStorageShare -Share $snapshot -Confirm:$false -Force
Within our DevOps script we are handling the removal as following:
$ToRemove = $StorageAccountShares | Where-Object { $_.Name -eq $ShareName -and $_.IsSnapshot -eq $true -and $_.SnapshotTime -lt $SnapShotExpireDate }
If ($ToRemove.Count -gt 0) {
Write-Output "$($SMsg)- Found $($ToRemove.Count) Snapshot(s) that has expired."
Write-Output "$($A)- Removing Snapshot(s) that have expired."
# Cleanup old snapshots
$Array = @()
Foreach ($I in $ToRemove){$Array += $I}
Foreach ($R in $ToRemove) {
If ($R.IsSnapshot -eq $true) {
$Index = ($Array.IndexOf($R)+1)
Write-Output ("$($A)- Removing Snapshot $($Index) of $($ToRemove.Count) - Snapshot date $($R.SnapshotTime.LocalDateTime)").PadLeft(10," ")
Remove-AzStorageShare -Share $R.CloudFileShare -Confirm:$false -Force
}
}
}
The $ToRemove variable is being filled with a list of snapshots. We need to make a filter in it. So we need to apply an extra filter on top of it. The following will do the trick:
$ToRemove = $StorageAccountShares | Where-Object { $_.Name -eq $ShareName -and $_.IsSnapshot -eq $true -and $_.SnapshotTime -lt $SnapShotExpireDate -and $_.CloudFileShare.Metadata.Initiator -ne 'AzureBackup' }
So if the “Initiator” is not equal to “AzureBackup” then it can be removed safely. Result is that the snapshots which are created by Azure Recovery Services Vaults are being held. At this point the Azure Recovery Services vault protection remains working for future restores.