【Azure】仮想マシンのシャットダウン方法には気をつけましょう

今月のAzure利用料を見てみようと明細を見てみたところ、仮想マシンは全てシャットダウンしてあったはずなのに結構な額がチャージされていました。サポートに問い合わせたところ、Azureの仮想マシンはシャットダウン方法によっては仮想マシンが起動していなくても課金されてしまうようです。




このAzureポータルの画像ですが、全てシャットダウンされています。しかし状態の列を見ると仮想マシンの状態として「停止済み」と「停止済み(割り当て解除済み)」という2種類のステータスが見えると思います。ここが重要になります。

ここで「停止済み」のステータスのものは仮想マシンがシャットダウンされていても課金されています

ここで言う「停止済み」というのは仮想マシンのOSはシャットダウンされていてもコンピュータリソースやIPアドレスなどのリソースはアサインされたままの状態を指していて、課金が続いていきます。(逆にメリットもあって、IPアドレスが解放されないことなどが、この状態の代表的なメリットです。グローバルIPアドレスを解放したくない場合はクラウドサービスに対して1台XSなどの小さいマシンを立ち上げておく方法などが考えられます)

実はこの二つの停止済みステータスはシャットダウンの方法によって変わってきます。
以下にシャットダウン方法別のステータスを纏めてみました。

シャットダウン方法 仮想マシンの状態 課金有無
仮想マシンWindows OSからシャットダウン 停止済み 課金有り
仮想マシンLinuxでshutdownコマンド 停止済み 課金有り
Azureポータルからシャットダウン 停止済み(割り当て解除済み) 課金無し
PorwerShell(Stop-AzureVM)利用 停止済み(割り当て解除済み) 課金無し




以下、もう少し詳しく書いてみます。

OS標準のシャットダウンは注意

まずはこれを覚えておきましょう。
リモートデスクトップでAzure上の仮想マシンにログインしてWindowsのシャットダウン操作をしただけでは課金は止まりません!LinuxのShutdownコマンドも同じです。仮想マシンOSレベルのシャットダウンではリソースが解放されず課金は止まりません


通常はAzureポータルのシャットダウンを利用

ではどうやればシャットダウンにより課金されなくなるのかと言うと、Azureポータルのシャットダウンボタンを利用することで課金が無いシャットダウンになります。

なお、シャットダウンボタンは「停止済み」のステータスの仮想マシンにも実行できます。(その場合は「停止済み」→「停止済み(割り当て解除済み)」とステータス遷移します。)


自動化などの場合はPowerShellコマンドレットStop-AzureVM利用

もし自動化したい場合などはAzure管理用のPowerShellコマンドレットのStop-AzureVMを利用します。

Azure管理用のPowerShellコマンドレットはこちらからダウンロードできます。
Download Windows Azure SDKs and Tools | Windows Azure


該当のコマンドのリファレンスはこちら。
Stop-AzureVM
http://msdn.microsoft.com/en-us/library/dn495269.aspx



使い方は以下の通りです。

PS > Stop-AzureVM -ServiceName "サービス名" -Name "VM名" -Force

※-StayProvisionedオプションを利用すると「停止済み」のステータスとし割り当てられているリソースを保持することもできます。(つまり、このオプションを付けた場合は課金が続きます)



引数に使っているサービス名やVM名を確認したい場合はGet-AzureVMコマンドを利用します。

PS > Get-AzureVM
ServiceName    Name    Status
-----------    ----    ------
サービス名    VM名   VMの状態


このコマンドも「停止済み」のステータスのもの対しても実行できます。

例えば、アプリケーションの停止順序を決めてシャットダウンしたい場合は、Azure上の仮想マシン上に配置したシステム停止用のスクリプトなどにStop-AzureVMコマンド組み込んでを呼ぶことができます。


割り当て解除の自動化

検証環境などの用途で何台も仮想マシンを持っている場合、私のようにシャットダウン方法間違って、大量の課金をされてしまうことがあるかもしれません。簡単ですが、「停止済み」ステータスの仮想マシンを選択してリソース割り当てを削除し、「停止済み(割り当て解除済み)」に変更、課金されないようにするPowerShellです。(起動している仮想マシンには影響しません)どこかのサーバー上のタスクで定期実行しておけば割り当て削除済みを防げると思います。

Get-AzureVM | Where-Object{$_.Status -eq "StoppedVM"} | ForEach-Object{Stop-AzureVM -ServiceName $_.ServiceName -Name $_.Name -Force}

正直、思わぬ課金は痛かったのですが、サポートの方が真摯に対応してくださり、仕組を良く理解できてたので、今回は勉強代ということで納得できました。