開発用 Azure VM の自動停止
個人開発用に使っている Azure Virtual Machines の使用料を節約するためにやっていることを紹介します。
背景
開発用 VM は 使いたいときに起動し、 使い終わったら停止 しています。
停止し忘れて無駄な課金が発生することがよくあったため、自動停止するようにしました。
方針
以下の方針で、自動停止を実装しました。また、起動するための処理の実装も必要だと分かりました。
- 定期的に停止
- 「X 時間ごとに」停止することで止め忘れを防止します。
- VM の自動シャットダウン機能だと、1 日 1 回しか停止できず不便なので、ほかの方法を検討しました。
- ディスク SKU の変更
- 使わないときはもっとも安いディスク(Standard HDD)
- 停止時に Standard HDD にする
- 使うときは高性能なディスク (Premium SSD)
- 起動時に Premium SSD にする
- 使わないときはもっとも安いディスク(Standard HDD)
使用技術
Azure Automation の Runbook を作成することとしました。
- 停止 Runbook : スケジュールと紐づける
- 起動 Runbook : 手動実行
Runbook
起動 Runbook
Param(
[string]$ResourceGroupName,
[string]$VMName
)
$TargetSku = 'Premium_LRS'
$Conn = Get-AutomationConnection -Name 'AzureRunAsConnection'
Connect-AzAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationId $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint
$VM = Get-AzVM -Name $VMName -ResourceGroupName $ResourceGroupName -Status
$VMState = $VM.Statuses[1].DisplayStatus
if (($VMState -eq "VM deallocated") -or ($VMState -eq "VM stopped")) {
foreach ($VMDisk in $VM.Disks) {
$Disk = Get-AzDisk -ResourceGroupName $ResourceGroupName -DiskName $VMDisk.Name
if ($Disk.Sku -eq $TargetSku) {
continue
}
$Disk.Sku = [Microsoft.Azure.Management.Compute.Models.DiskSku]::new($TargetSku)
$Disk | Update-AzDisk
}
Start-AzVM -Name $VMName -ResourceGroupName $ResourceGroupName
}
停止 Runbook
Param(
[string]$ResourceGroupName,
[string]$VMName
)
$TargetSku = 'Standard_LRS'
$Conn = Get-AutomationConnection -Name 'AzureRunAsConnection'
Connect-AzAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationId $Conn.ApplicationID -CertificateThumbprint $Conn.CertificateThumbprint
$VM = Get-AzVM -Name $VMName -ResourceGroupName $ResourceGroupName -Status
$VMState = $VM.Statuses[1].DisplayStatus
if (($VMState -eq "VM deallocated") -or ($VMState -eq "VM stopped")) {
Write-Output 'The VM already stopped.'
} else {
Stop-AzVM -Name $VMName -ResourceGroupName $ResourceGroupName -Force
}
foreach ($VMDisk in $VM.Disks) {
$Disk = Get-AzDisk -ResourceGroupName $ResourceGroupName -DiskName $VMDisk.Name
if ($Disk.Sku -eq $TargetSku) {
continue
}
$Disk.Sku = [Microsoft.Azure.Management.Compute.Models.DiskSku]::new($TargetSku)
$Disk | Update-AzDisk
}
改善点
作業中の VM 停止の対処
現状だと、スケジュールどおりに自動停止されてしまいます。
「何時までは停止スケジュールを無効にしてね(何時から停止スケジュールを有効にしてね)」というスケジュールを手動設定できるようにしたいです。