Imagine you had a whole lot of data stored in Azure, you also want to save the most money in storage costs. By default, Azure Blob Storate is set to the Hot tier for all blobs, the most expensive storage costs, but the cheapest to read.
To give you an idea of the cost savings, here are General Purpose v2 storage account pricing below as of time of publication in US dollars:
HOT | COOL | ARCHIVE | |
Storage | First 50 terabyte (TB) / month | $0.0208 per GB | $0.0152 per GB | $0.0025 per GB |
Storage | Next 450 TB / Month | $0.02 per GB | $0.0152 per GB | $0.0025 per GB |
Storage | Over 500 TB / Month | $0.0192 per GB | $0.0152 per GB | $0.0025 per GB |
Read Operations** (per 10,000) | $0.0044 | $0.01 | $5.50 |
To upgrade to a v2 storage account, it’s super easy.
With a v2 storage account, you only have the option of setting the Storage Tier at the entire storage account level, or manually by individual blobs (which can be an administration nightmare) – until now.
I have written a PowerShell script that will automate the process of setting the Tier on files (blobs) older than a specific number of days which you specify. Then you let the script to the work, it can be run interactively or fully automatic using Azure Automation.
This script will scan a designated storage account for all blobs, then it will then set the tier (Hot, Cool or Archive) for each blob that is older then a retention period of days in which you specify.
Setting object level access tier is only supported for Standard (LRS/GRS/RA-GRS) Blob Storage and General Purpose V2 Accounts. See https://aka.ms/blobtiering
There’s two scripts, the script below which can be run interactively, it will ask you questions for the storage account, tier & days retention. Or here, there is an Azure Automation runbook which I published, you can setup a schedule and run this on a daily basis across your storage accounts.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#region Install Modules | |
# Run as Administrator | |
#Find-Module AzureServicePrincipalAccount | Install-Module | |
#endregion | |
# Retrieve Azure Module properties | |
"" | |
"Validating installed PowerShell Version and Azure PowerShell Module version…" | |
$ReqVersions = Get-Module Azure –list | Select-Object Version, PowerShellVersion | |
# Current PowerShell version must be higher then the one required by the Azure Module | |
if($PSVersionTable.PSVersion.Major -lt $ReqVersions.PowerShellVersion.Major) | |
{ | |
$PSVerReq = $ReqVersions.PowerShellVersion | |
$PSVerInst = $PSVersionTable.PSVersion | |
"Validation failed…" | |
"Installed PowerShell version: $PSVerInst" | |
"Powershell version $PSVerReq required. Please update the version of Powershell on this system" | |
"Exiting Script" | |
Break | |
} | |
# Current script was tested with Azure module 5.0.1 | |
if($ReqVersions.Version.Major -lt 5) | |
{ | |
$AZModuleInst = $ReqVersions.Version | |
"Validation failed…" | |
"Installed Azure PS Module: $AZModuleInst. This script was tested with version 5.0.1" | |
"Please download and install/update the Azure Powershell module using the Microsoft Web Platform Installer…" | |
"Download link: https://github.com/Azure/azure-powershell/releases/tag/v5.0.1-November2017" | |
"Exiting Script" | |
Break | |
} | |
########################################################################################## | |
################################# Logon to Azure ################################## | |
########################################################################################## | |
Login–AzureRmAccount | |
#region Logon to Azure & choose Azure subscription | |
$Subscription = (Get-AzureRmSubscription | Out-GridView –Title "Choose a Source & Target Subscription …" –PassThru) | |
Select-AzureRmSubscription –Subscription $Subscription | |
$SubscriptionId = $Subscription.Id | |
#endregion | |
#### Question time #### | |
# Question 1 – Select Desired Storage Tier | |
$StorageTiers = @('Hot', 'Cool', 'Archive') | |
$StorageTier = ($StorageTiers | Out-GridView –Title "Select a storage tier …" –PassThru) | |
# Question 2 – Storage Account | |
$StorageAccounts = Get-AzureRmStorageAccount | | |
Where-Object {($_.sku.tier -eq 'Standard') -and ($_.Kind -eq 'StorageV2' -or $_.Kind -eq 'BlobStorage')} | |
$StorageAccount = ($StorageAccounts | select StorageAccountName, PrimaryLocation, ResourceGroupName | | |
Out-GridView –Title "Select the V2 Standard Storage Account you want to scan for blob candidates …" –PassThru) | |
$StorageAccountName = $StorageAccount.StorageAccountName | |
# Question 3 – Days Retention | |
write-host –nonewline "Enter the number of days retention you want to set, the tier will be set on any older blobs: " –ForegroundColor Green | |
[int]$DaysOld = read-host | |
# Setup the Storage Connection stuff | |
$StgAcct = Get-AzureRmStorageAccount | Where-Object {($_.StorageAccountName -eq $StorageAccountName) -and ($_.sku.tier -eq 'Standard') ` | |
-and ($_.Kind -eq 'StorageV2' -or $_.Kind -eq 'BlobStorage')} | |
if ($StgAcct) { | |
$StgAcctKey = (Get-AzureRmStorageAccountKey –ResourceGroupName $StgAcct.ResourceGroupName ` | |
–Name $StgAcct.StorageAccountName).Value[0] | |
$StgAcctContext = New-AzureStorageContext –StorageAccountName $StgAcct.StorageAccountName ` | |
–StorageAccountKey $StgAcctKey | |
$StorageContainers = Get-AzureStorageContainer –Context $StgAcctContext | |
# Cycle through all blobs in the storage account | |
$Blobs = @() | |
foreach($StorageContainer in $StorageContainers){ | |
$Blobs += Get-AzureStorageBlob –Context $StgAcctContext –Container $StorageContainer.Name | |
} | |
# Date Logic | |
$UTCDate = (Get-Date).ToUniversalTime() | |
$RetentionDate = $UTCDate.AddDays(–$DaysOld) | |
$EarmarkedBlobs = $Blobs | Where-Object {$_.lastmodified.DateTime -le $RetentionDate} | |
# Change the Tier on the blobs | |
Foreach($Blob in $EarmarkedBlobs){ | |
#Set tier of all blobs to desired tier | |
$blob.icloudblob.SetStandardBlobTier($StorageTier) | |
} | |
cls | |
Write-Host –ForegroundColor Green "`n`nDone… Complete. Check your Blog Tiers in the portal.`n" | |
} else { | |
Write-Error "Your selected Storage account cannot be used, most likely because it's ` | |
not a V2 Storage account, a blob storage account or it's not a Standard Storage account" | |
} |