AzureVMを起動/停止/再起動/状態確認するAzure Automation
はじめに
AzureでVMの起動停止などの操作をユーザにさせる場合、都度カスタムロールを作成/修正して割り当てる方法があります。
運用者にロールの編集権限を与えておくのは危険なので、Azure Automationを使って何とか作ってみました。
概要
以下のようなAutomationアカウントを作成します。
- 変数に、操作させたいVMのリソースIDを指定
- 運用者が指定する想定です。
- 操作するRunbookから上記の変数を取得して、入力時に指定したVMが操作してよいVMかどうかを確認
権限については以下のように運用します。
- 操作者に対して、上記AutomationアカウントのAutomation オペレーターの権限を作成
- 運用者には、上記の権限を付与だけできるようにしておく
参考
作成
Azure Automation アカウント・ランタイム作成
過去の記事と同じものを作成します。ランタイムも現時点で最新版のPowerShell7.4で作ります。
デフォルトのランブックの削除
作成時にデフォルトでランブックがありますので、消しておきます。
ランブック作成
作成の仕方は以前の記事を参照ください。
スクリプトは以下になります。
param(
[Parameter(Mandatory=$true)][string]$executionId,
[Parameter(Mandatory=$true)][string]$ResourceId,
[Parameter(Mandatory=$true)][ValidateSet("GetVmInfo","Start", "Stop", "Restart")][string]$Action
)
$ErrorActionPreference = "Stop" # エラーが発生したらスクリプトを終了
# connect to Azure
try {
Write-Output "Trying to connect to Azure with a system assigned Identity..."
$null = Connect-AzAccount -Identity
}catch {
$ErrorMessage = "Error connecting to Azure: " + $_.Exception.message
Write-Error $ErrorMessage
}
# 変数取得
try{
$retVar = Get-AutomationVariable -Name $executionId
}catch {
$ErrorMessage = "指定したexecutionId: $($executionId) が存在しません。`r`n "
$ErrorMessage += "Error connecting to Azure: " + $_.Exception.message
Write-Error $ErrorMessage
}
# リソースIDが定義されているか確認し実行
if( ($retVar -split ',' ).Contains($ResourceId) ){
# リソースIDから各引数を抽出
$AryResourceId = $ResourceId.Split('/')
$SubscriptionId = $AryResourceId[2]
$RgName = $AryResourceId[4]
$VmName = $AryResourceId[-1]
# リソースIDからサブスクリプションIDを取得し、プロファイルを取得
try{
Write-Output "サブスクリプションID $($SubscriptionId) のプロファイルを取得します."
$TargetProfile = Set-AzContext -SubscriptionId $SubscriptionId
}catch {
$ErrorMessage = "エラーが発生しました.サブスクリプションID: $($SubscriptionId) のプロファイルが取得できません。`r`n "
$ErrorMessage += $_.Exception.message
Write-Error $ErrorMessage
}
try {
Write-Output "リソースID $($ResourceId) に対して、$($Action) 実行中..."
switch ($Action) {
"GetVmInfo" {
(Get-AzVM -ResourceGroupName $RgName -Name $VmName -DefaultProfile $TargetProfile -status).Statuses[1].Code }
"Start" { Start-AzVM -ResourceGroupName $RgName -Name $VmName -DefaultProfile $TargetProfile }
"Stop" { Stop-AzVM -ResourceGroupName $RgName -Name $VmName -Force -DefaultProfile $TargetProfile }
"Restart" { Restart-AzVM -ResourceGroupName $RgName -Name $VmName -DefaultProfile $TargetProfile }
}
Write-Output "処理は終了しました。"
}catch {
$ErrorMessage = "エラーが発生しました: " + $_.Exception.message
Write-Error $ErrorMessage
}
}else {
$ErrorMessage = "リソースID $($ResourceId) は変数で未定義のため、実行は許可されていません "
Write-Error $ErrorMessage
}
Errorについては何も設定しないと処理を続けてしまうので、以下を参考にしました。
カスタムロール作成・割り当て
Automation アカウントに紐づけるカスタムロールを作成します。
スコープはサブスクリプション全体で、アクションは 起動/割り当て解除/再起動/読み取り を持つロールを作成します。
JSONだと以下のようになります。
{
"properties": {
"roleName": "cr-operateVm",
"description": "",
"assignableScopes": [
"/subscriptions/[対象のサブスクリプションID]"
],
"permissions": [
{
"actions": [
"Microsoft.Compute/virtualMachines/start/action",
"Microsoft.Compute/virtualMachines/read",
"Microsoft.Compute/virtualMachines/restart/action",
"Microsoft.Compute/virtualMachines/deallocate/action"
],
"notActions": [],
"dataActions": [],
"notDataActions": []
}
]
}
}
作成したカスタムロールを、作成したAutomation アカウントに割り当てます。
今回はマネージドIDから割り当ててみます。IDからシステム割り当て済み よりAzureロールの割り当てをクリックします。
ロールの割り当ての追加から、サブスクリプションスコープで作成したロールを割り当てます。
操作者用の権限作成
操作者には都度、このAutomationアカウントへのオペレータ権限を付与します。
運用者には、ユーザアクセス管理者として、Automation オペレータの権限を付与できるようにしておきます。
設定・実行
使い方は変数として許可するVMのリソースIDを定義していきます。
変数設定
変数から、名前に実行IDを、値に操作させたいVMのリソースIDをカンマ区切りで指定します。実行IDはユーザの名前など、任意の文字列を指定できます。制限はこちらを確認ください。
実行
実行する際は、先ほど変数で指定した内容と処理を引数として指定します。
ACTIONには、GetVmInfo/Start/Stop/Restart を指定してください。
出力タブで、結果を確認します。
おわりに
今回はAzure Automationを用いて、権限を編集する権限を使わないでAzureVMの操作を行えるような仕組みを考えてみました。
AWSのようにカスタムロールの中でcondition句を使えないので、このような形にしました。
この記事がどなたかのお役に立ちましたら幸いです。
Discussion