【Azure】PowerShellでBLOB上のVHDのSnapshot作成・取得・削除の操作をする

BLOBのスナップショットですが、AWSのManagement ConsoleのようにAzureのポータルからスナップショットの取得などの操作ができるのかと思ってたのですができないみたいです。(調べたりないのかも)そこで、MSDNを探したところ、C#のコードでやるように書かれていました。
Creating a Snapshot of a Blob


個人的にはC#の方が幾分得意なのですが、せっかくなので、今回はPowerShellでスナップショットの基本的な操作について書こうと思います。

Snapshotについて

SnapShotの特徴は以下のページ(英語)に記載があります。
http://msdn.microsoft.com/ja-jp/library/azure/hh488361.aspx

特にBlobのコピーと比較すると課金が異なるのですが、そこは日本語で丁寧に説明されています。
スナップショットの課金方法について
 



PowerShell

では早速PowerShellでのBLOB操作について書いていきます。

元にしたスクリプトはこちらです。結構しっかりと書かれているのでこのままでも使えますが、この記事では単機能ごとに切り出して抽出してみたいと思います。
Script Backup and Restore Windows Azure IaaS Virtual Machines using BLOB Snapshots
 
 
 
 

まず全スクリプト共通の初期化設定についてです。

PowerShellのAzureモジュールをインポート

事前設定としてこちらからAzure操作用のPowerShellモジュールをダウンロードして、インストールします。スクリプト内ではインストール済みのAzureモジュールをインポートして利用します。

#デフォルトのインストールフォルダです。64bitの場合はフォルダ名が異なります。
Import-Module "C:\Program Files\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1"

 
 
 
 

パラメータ値の準備(Windows Azure接続文字列)

AzureのBLOBにアクセスするためには接続文字列を準備する必要があります。詳しくはこちらのページに書かれています。
Configuring Azure Connection Strings

書式は以下のようになります。まずはこの文字列を作ります。

DefaultEndpointsProtocol=[http|https];AccountName=myAccountName;AccountKey=myAccountKey

必要な情報はAzureポータルのストレージのダッシュボード画面から「アクセスキーの管理」を選択することで取得できます。

上画面の情報をPowerShellで設定してみます。

$protocol = "https" #http or https
$storageAccountName = "xxxxxxxx" #ストレージアカウント名
$primaryKey = "xxxxxxxxxxxxxxxxxxx" #プライマリアクセスキー
$connectionString = "DefaultEndpointsProtocol=$($protocol);AccountName=$($storageAccountName);AccountKey=$($primaryKey)"

 
 
 
 

パラメータ値の準備(コンテナのエンドポイント)

今度はBLOBのコンテナの情報を設定します。AzureポータルからストレージアカウントのコンテナーからURLを取得できます。

$blobContainerUrl = "http://xxxxx.xxxxx.xxxxx.xxxxx/vhds"

 
 
 
 

パラメータ値の準備(BLOBのエンドポイント)

更にコンテナーの中のBLOBのURLを取得します。

$blobUrl = "http://xxxxx.xxxx.xxxx.xxxx/vhds/xxxxxxxxxxx.vhd"

 
 
 
 

スナップショットの作成

ここまでで取得したパラメータを利用してCloudBlobオブジェクトを生成できるようになるので、これを利用してスナップショットの操作をしていきます。

CloudBlobオブジェクトのメンバはこちらから確認できます。
CloudBlob Members (Microsoft.WindowsAzure.StorageClient)

CreateSnapshotメソッドでスナップショットが作成できます。

#デフォルトのインストールフォルダです。64bitの場合はフォルダ名が異なります。
Import-Module "C:\Program Files\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1"

#Azureストレージアカウント情報の設定
$protocol = "https" #http or https
$storageAccountName = "xxxxxxxx" #ストレージアカウント名
$primaryKey = "xxxxxxxxxxxxxxxxxxx" #プライマリアクセスキー
$connectionString = "DefaultEndpointsProtocol=$($protocol);AccountName=$($storageAccountName);AccountKey=$($primaryKey)"

#BLOBの情報設定
$blobUrl = "http://xxxxx.xxxx.xxxx.xxxx/vhds/xxxxxxxxxxx.vhd"

#スナップショットの作成
if($connectionString -ne $null)
{
	[Microsoft.WindowsAzure.Storage.CloudStorageAccount]$storageAccount = [Microsoft.WindowsAzure.Storage.CloudStorageAccount]::Parse($connectionString)
	[Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient]$client = $storageAccount.CreateCloudBlobClient()
	$blob = $client.GetBlobReferenceFromServer($blobUrl)
}
#作成したスナップショットの情報が表示されます
$blob.CreateSnapshot()

もし上記のスクリプトが動かない場合はこちらの修正をしてみてください。

×$blobContainerUrl = "https://storage01ns.blob.core.windows.net/vhds"$blobContainerName = "vhds"

×[Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer]$container = $client.GetContainerReference($blobContainerUrl)
→[Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer]$container = $client.GetContainerReference($blobContainerName)

 
 
 

スナップショットの一覧取得

同じように作成したスナップショットを確認するスクリプトです。コンテナ内のスナップショットの一覧をresults変数に入れて表示してます。

#デフォルトのインストールフォルダです。64bitの場合はフォルダ名が異なります。
Import-Module "C:\Program Files\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1"

#Azureストレージアカウント情報の設定
$protocol = "https" #http or https
$storageAccountName = "xxxxxxxx" #ストレージアカウント名
$primaryKey = "xxxxxxxxxxxxxxxxxxx" #プライマリアクセスキー
$connectionString = "DefaultEndpointsProtocol=$($protocol);AccountName=$($storageAccountName);AccountKey=$($primaryKey)"

#BLOBの情報設定
$blobUrl = "http://xxxxx.xxxx.xxxx.xxxx/vhds/xxxxxxxxxxx.vhd"
$blobContainerUrl = "http://xxxxx.xxxxx.xxxxx.xxxxx/vhds"

#スナップショット一覧取得
$results = @()

if($connectionString -ne $null)
{		
	[Microsoft.WindowsAzure.Storage.CloudStorageAccount]$storageAccount = [Microsoft.WindowsAzure.Storage.CloudStorageAccount]::Parse($connectionString)
	[Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient]$client = $storageAccount.CreateCloudBlobClient()			
	[Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer]$container = $client.GetContainerReference($blobContainerUrl)
	
	$blobListing = $container.ListBlobs('', $true, [Microsoft.WindowsAzure.Storage.Blob.BlobListingDetails]::Snapshots)
	
	foreach($blob in $blobListing)
	{
        #スナップショットの場合はSnapshotTimeのプロパティに値が設定されています
		if($blob.SnapshotTime -ne $null)
		{
                        #変数resultsにスナップショットの一覧が格納されます
			$results += $blob
		}
	}
	
}

#スナップショットの情報一覧が表示されます	
$results

もし上記のスクリプトが動かない場合はこちらの修正をしてみてください。

×$blobContainerUrl = "https://storage01ns.blob.core.windows.net/vhds"$blobContainerName = "vhds"

×[Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer]$container = $client.GetContainerReference($blobContainerUrl)
→[Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer]$container = $client.GetContainerReference($blobContainerName)

 
 
 

スナップショットの全削除

削除の方法も書いておきます。このスクリプトの場合はコンテナ内の全てのスナップショットを削除してあります。オブジェクトはスナップショットの日付などの情報を持っているので、それらの情報でハンドリングしてあげればスナップショットの世代管理のようなことも可能です。

#デフォルトのインストールフォルダです。64bitの場合はフォルダ名が異なります。
Import-Module "C:\Program Files\Microsoft SDKs\Windows Azure\PowerShell\Azure\Azure.psd1"

#Azureストレージアカウント情報の設定
$protocol = "https" #http or https
$storageAccountName = "xxxxxxxx" #ストレージアカウント名
$primaryKey = "xxxxxxxxxxxxxxxxxxx" #プライマリアクセスキー
$connectionString = "DefaultEndpointsProtocol=$($protocol);AccountName=$($storageAccountName);AccountKey=$($primaryKey)"

#BLOBの情報設定
$blobUrl = "http://xxxxx.xxxx.xxxx.xxxx/vhds/xxxxxxxxxxx.vhd"
$blobContainerUrl = "http://xxxxx.xxxxx.xxxxx.xxxxx/vhds"

#コンテナ内のスナップショット全削除
if($connectionString -ne $null)
{		
	[Microsoft.WindowsAzure.Storage.CloudStorageAccount]$storageAccount = [Microsoft.WindowsAzure.Storage.CloudStorageAccount]::Parse($connectionString)
	[Microsoft.WindowsAzure.Storage.Blob.CloudBlobClient]$client = $storageAccount.CreateCloudBlobClient()			
	[Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer]$container = $client.GetContainerReference($blobContainerUrl)
	
	$blobListing = $container.ListBlobs('', $true, [Microsoft.WindowsAzure.Storage.Blob.BlobListingDetails]::Snapshots)
	
	foreach($blob in $blobListing)
	{
		if($blob.SnapshotTime -ne $null)
		{
			$blob.Delete()
		}
	}
	
}	

もし上記のスクリプトが動かない場合はこちらの修正をしてみてください。

×$blobContainerUrl = "https://storage01ns.blob.core.windows.net/vhds"$blobContainerName = "vhds"

×[Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer]$container = $client.GetContainerReference($blobContainerUrl)
→[Microsoft.WindowsAzure.Storage.Blob.CloudBlobContainer]$container = $client.GetContainerReference($blobContainerName)


  
 
 
 

スナップショットからBLOBの作成

新しい空のBLOBを作成してそこにスナップショットの内容をコピーする形で実現するようです。

#$myNewBlobには新しく作成した空のBLOBを入れておきます
#$snapshotにはスナップショットの参照を入れておきます。
$myNewBlob.StartCopyFromBlob($snapshot,$null, $null, $null, $null)
#非同期処理なので完了を待ちます
#コピーステータス監視
do
{
Start-Sleep -Seconds 30
$copyStatus = $client.GetBlobReferenceFromServer($myNewBlob.Uri.AbsoluteUri).CopyState.Status
Write-Host (Get-Date) ": Copy Status:" $copyStatus
}while($copyStatus -eq [Microsoft.WindowsAzure.Storage.Blob.CopyStatus]::Pending)
Write-Host (Get-Date) ": Copy Completed"

 
こちらも参考にしてください。
PowerShellでAzureストレージアカウント間のBLOBをコピーする - YOMON8.NET


 

参考情報

GUIでBLOBの操作をしたい場合は、BLOBストレージの管理ツールもあります。こちらは結構便利です。(スナップショット取れないみたいです。)
付録 E: Windows Azure ストレージ管理ツール

3rd Party製のツールもあるみたいで、こちらはスナップショット取れそうです。
Azure Explorer | Cerebrata


他のツールを含めた比較がWindows Azure Storageチームのブログに書かれています。
http://blogs.msdn.com/b/windowsazurestorage/archive/2014/03/11/windows-azure-storage-explorers-2014.aspx


自分でもスナップショット取得できるアプリ作ってみました。 
AzureのBLOBスナップショットを管理するためのアプリ作ってみました - YOMON8.NET