【Azure】AutomationアカウントでVMの起動/停止を定期的に繰り返すスケジュールを組む(ARMテンプレート編):Tech TIPS
Azure Automationで何らかの処理を自動化する際、PowerShellスクリプトなどのRunbookを定期的に繰り返し実行したいことがある。仮想マシン(VM)の起動/シャットダウンを例として、この定期スケジュールをAutomationアカウントのデプロイと同時に作成する方法とその注意点を説明する。
対象:Azure Automation、ARMテンプレート(Bicep)
Azure上での各種自動化のためのサービス「Azure Automation」では、「毎日1回」「3週に1回」といった定期的な実行をサポートしている。本Tech TIPSでは、Automationアカウントのデプロイ時にこの定期実行のスケジュールも一緒に作成する方法と注意点を説明したい。
例としては、定期的なVMの起動/シャットダウンを取り上げる。また、次のTech TIPSで説明しているRunbookの生成およびカスタムロール割り当てを前提としている。
以下では説明を簡単にするために、全リソースを特定の単一サブスクリプションにデプロイするものとし、かつ操作対象のVMはデプロイ済みとする(VMの生成方法は説明しない)。
各リソースを生成する前には、「az account set」コマンドを以下のように実行して、デフォルトのサブスクリプションを適切に選択していただきたい。
az account set -s <サブスクリプション名>
デプロイにはBicepで記述したARM(Azure Resource Manager)テンプレートを使用する。また、掲載しているAzure CLIのコマンドラインは、Windows OSのコマンドプロンプトで実行することを前提としている。
■執筆時の各種ツール/APIのバージョン
- Azure CLI: Ver. 2.60.0
- Bicep CLI: Ver. 0.27.1
- Bicepでのデプロイ時のAPIバージョン: 2023-11-01(Automationアカウント)
スケジュールの開始日時や繰り返し方、タイムゾーンなどを定義する
以下では、AutomationアカウントをデプロイするためのARMテンプレートファイル「main.bicep」を4つに分割して説明する。
最初のセクションでは、定期実行するスケジュールの開始時刻などをパラメーターで受け取りつつ、配列「schedules」にまとめている。
// ファイル: main.bicep(1/4)
// 制御対象のVM
param VMName string // 起動/シャットダウンする対象の仮想マシン名
param VMRG string // ↑のリソースグループ
// VMの起動/シャットダウン時刻とそのタイムゾーン
param VMStartTimeLocal string = '03:00:00' // VM起動時刻
param VMStopTimeLocal string = '09:00:00' // VMシャットダウン時刻
param timeZoneAbb string = 'JST' // ↑で指定する時刻のタイムゾーン略称
var timeZones = {
// 各タイムゾーン。ここでは日本時間のみ定義
JST: {
id: 'Asia/Tokyo'
offset: '+09:00'
duration: 'PT9H'
description: '日本時間'
}
}
var timeZone = timeZones[timeZoneAbb] // 日本時間のオフセットや継続時間など
// VM起動/シャットダウンの定期実行を始める日を算出
param now string = utcNow() // デプロイ時刻(UTC)
// ↑utcNow()はパラメーターのデフォルト値としてのみ指定可能(変数に代入するとエラーになる)
var nowLocal = dateTimeAdd(now, timeZone.duration) // ↑の日本時間
var tomorrowLocal = dateTimeAdd(nowLocal, 'P1D', 'yyyy-MM-dd')
// ↑デプロイの翌日から起動/シャットダウンを始める想定。年月日のみを日本時間で表記
var neverExpiryTime = '9999-12-31T23:59:59.9999999+00:00' // 無期限を表す
// 定期実行のスケジュール一覧
var schedules = [
{
// スケジュール: VM起動
name: 'start-${VMName}' // このスケジュールの一意な名前
description: '仮想マシン「${VMName}」を毎日${VMStartTimeLocal}(${timeZone.description})に起動する'
startTime: '${tomorrowLocal}T${VMStartTimeLocal}${timeZone.offset}'
// ↑ジョブ開始日時(=VM起動日時)。「2024-05-16T04:00:00+09:00」のように指定
expiryTime: neverExpiryTime // 有効期限。ここでは無期限
frequency: 'Day' // 繰り返す単位。ここでは「日」
interval: 1 // 繰り返す間隔。ここでは↑との組み合わせで「毎日」
runbookName: runbooks.startStopVM.name // 実行するRunbookの名称
runbookParams: {
// 実行するRunbookに渡すパラメーター(個々のRunbookに依存)
ACTION: 'Start' // 「VM起動」を指定
VMNAME: VMName // 対象VMの名前
RESOURCEGROUPNAME: VMRG // 対象VMのリソースグループ
AZURESUBSCRIPTIONID: subscription().subscriptionId
}
}
{
// スケジュール: VMシャットダウン
name: 'stop-${VMName}'
description: '仮想マシン「${VMName}」を毎日${VMStopTimeLocal}(${timeZone.description})にシャットダウン/割り当て解除する'
startTime: '${tomorrowLocal}T${VMStopTimeLocal}${timeZone.offset}'
// ↑ジョブ開始日時(=VMシャットダウン日時)
expiryTime: neverExpiryTime
frequency: 'Day'
interval: 1
runbookName: runbooks.startStopVM.name
runbookParams: {
ACTION: 'Stop' // 「VMシャットダウン/割り当て解除」を指定
VMNAME: VMName
RESOURCEGROUPNAME: VMRG
AZURESUBSCRIPTIONID: subscription().subscriptionId
}
}
]
※Microsoftのレファレンス:Microsoft.Automation automationAccounts/schedules、Microsoft.Automation automationAccounts/jobSchedules
パラメーター「VMStartTimeLocal」にはVMの起動時刻を、例えば「03:00:00」(日本時間で午前3時)というように指定する。同様に「VMStopTimeLocal」にはシャットダウン時刻を指定する。
Automationアカウントのスケジュールでは、UTCとは異なるローカルなタイムゾーンで開始日時などを指定できる。パラメーター「timeZoneAbb」には、そのタイムゾーンを「JST」といった略称で指定する。そこから「Asia/Tokyo」「+09:00」「PT9H」といった異なる表記を導き出せるように、オブジェクト「timeZones」を定義している(後述するARMテンプレートでは、異なる表記でタイムゾーンを指定する必要があるため)。
Automationで定期的なスケジュールを組むには、「開始日時」「繰り返す単位」「繰り返す間隔」をそれぞれ指定する必要がある。上記の配列「schedules」なら、それぞれ「startTime」「frequency」「interval」に該当する。上記リストでは翌日の指定時刻より毎日1回ずつ実行するように設定している。3日に1回実行するなら「interval」に「3」を、また週単位なら「frequency」に「week」をそれぞれ指定すればよい。
配列「schedules」内の「runbookParams」の内容は、Runbook(ここではPowerShellスクリプト)に依存する。スクリプトの仕様を確認して、必要なパラメーター名とその値を列挙すること。
「スケジュール」と「ジョブスケジュール」の両リソースを生成する必要がある
Automationアカウントで定期的なスケジュールを組むには、「Microsoft.Automation/automationAccounts/schedules」(スケジュール)」と「Microsoft.Automation/automationAccounts/jobSchedules」(ジョブスケジュール)という紛らわしい名前のリソースを両方とも生成する必要がある。前者は実行日時(開始日時、繰り返しの単位、間隔、タイムゾーン)を定義し、後者はRunbookとスケジュールをひも付ける。
// ファイル: main.bicep(2/4)
// リソース生成: スケジュール(開始日時とその後の間隔などの設定)
resource automationSchedule 'Microsoft.Automation/automationAccounts/schedules@2023-11-01' = [
for sch in schedules: {
parent: automationAccount // 親リソースのAutomationアカウント
name: sch.name // このスケジュールの名前
properties: {
description: sch.description // 説明
timeZone: timeZone.id // タイムゾーン
startTime: sch.startTime // ↑のタイムゾーンに合わせたローカル時刻を指定
expiryTime: sch.expiryTime // 有効期限
frequency: sch.frequency // 繰り返しの単位
interval: sch.interval // 繰り返す間隔
}
}
]
// リソース生成: ジョブスケジュール(スケジュールとRunbookのひも付けなどの設定)
resource automationJobSchedule 'Microsoft.Automation/automationAccounts/jobSchedules@2023-11-01' = [
for (sch, i) in schedules: {
parent: automationAccount // 親リソースのAutomationアカウント
name: guid(VMName, automationAccount.id, automationSchedule[i].id)
// ↑ジョブごとに一意なGUID
properties: {
parameters: sch.runbookParams
runbook: {
name: sch.runbookName
}
schedule: {
name: sch.name
}
}
dependsOn: [
automationRunbook // Runbookのリソース。指定しないとエラーになる
]
}
]
※Microsoftのレファレンス: Microsoft.Automation automationAccounts/schedules、Microsoft.Automation automationAccounts/jobSchedules
上記リストでは、前述のスケジュール一覧の配列「schedules」をループで回して、スケジュールごとにリソースを生成している。
ジョブスケジュールでは「name」にユニークなGUIDを指定する必要がある。上記リストでは、guid()関数を使ってVMの名前とAutomationアカウントのID、スケジュールのIDからハッシュ値を計算してGUIDを導出している。
Runbookのリソースを生成する
次はRunbookのリソース生成である。ここでは、「Simple-Azure-VM-Start-Stop」というAzure上の仮想マシンを起動またはシャットダウンするためのスクリプトを、GitHubから直接Runbookへインポートしている。詳細はTech TIPS「【Azure】Automation RunbookにGitHub上のPowerShellスクリプトをインポートする(ARMテンプレート編)」を参照していただきたい。
// ファイル: main.bicep(3/4)
// インポートするRunbook用スクリプトの一覧
var runbooks = {
// https://github.com/diecknet/Simple-Azure-VM-Start-Stop
startStopVM: {
// ↑前述のジョブスケジュールから参照するため、配列ではなく
// オブジェクトとして定義し、キー名でRunbookを特定している
name: 'Simple-Azure-VM-Start-Stop' // 識別しやすい名称を付ける
description: 'Start or Stop the specified VM.' // 説明
runbookType: 'PowerShell' // これはPowerShell 5.1の場合
// ↑PowerShell 7.2なら「PowerShell72」
publishContentLink: {
uri: 'https://raw.githubusercontent.com/diecknet/Simple-Azure-VM-Start-Stop/main/SimpleAzureVMStartStop.ps1'
// ↑スクリプトのダウンロードURL
}
}
}
// リソース生成: Runbooks
resource automationRunbook 'Microsoft.Automation/automationAccounts/runbooks@2023-11-01' = [
for runbook in items(runbooks): {
parent: automationAccount // 親リソースのAutomationアカウント
location: location
name: runbook.value.name // 「.value」でオブジェクトの値を参照
properties: {
description: runbook.value.description
runbookType: runbook.value.runbookType
publishContentLink: runbook.value.publishContentLink
}
}
]
※Microsoftのレファレンス:Microsoft.Automation/automationAccounts/runbooks、for、items()
Automationアカウントのリソース生成とVM起動/シャットダウン許可のカスタムロール割り当て
main.bicepの最後は、Automationアカウント本体のリソース生成と、対象VMの起動やシャットダウンを許可するためのカスタムロール割り当てもしている。詳細はTech TIPS「【Azure】VMの起動/シャットダウンができるカスタムロールを割り当てつつAutomationをデプロイ(ARMテンプレート編)」を参照していただきたい。
// ファイル: main.bicep(4/4)
param automationAccountName string // Automationアカウントのリソース名
param location string = resourceGroup().location
param publicNetworkAccess bool = true // パブリックネットワークからのアクセスの可否
param disableLocalAuth bool = false // ローカル認証の可否
var identity = {
type: 'SystemAssigned' // マネージドID: システム割り当て
}
var sku = {
name: 'Basic' // SKU: Basic
}
var encryption = {
keySource: 'Microsoft.Automation' // 暗号化: デフォルトのまま
identity: {}
}
// リソース生成: Automationアカウント
resource automationAccount 'Microsoft.Automation/automationAccounts@2023-11-01' = {
name: automationAccountName
location: location
identity: identity
properties: {
publicNetworkAccess: publicNetworkAccess
disableLocalAuth: disableLocalAuth
sku: sku
encryption: encryption
}
}
////////////////////////////////////////
// VMの起動/シャットダウンを許可するカスタムロールを割り当てる
param definedRoleId string // カスタムロールのID
param roleAssignDesc string = 'VM起動/シャットダウン許可のカスタムロール割り当て' // このロール割り当ての説明文
var roleAssignScope = resourceGroup(VMRG)
// ↑VMと同じリソースグループに、このロール割り当てリソースを生成
var assignedPrincipalId = automationAccount.identity.principalId
// ↑このロールの割り当て先。AutomationアカウントのプリンシパルIDを指定
var assignedPrincipalType = 'ServicePrincipal' // ↑のIDの種別
// モジュール: ロール割り当て
module roleAssignModule './roleassign.bicep' = {
name: '${deployment().name}-roleAssign'
scope: roleAssignScope
params: {
description: roleAssignDesc
definedRoleId: definedRoleId
principalId: assignedPrincipalId
principalType: assignedPrincipalType
}
}
※Microsoftのレファレンス:Microsoft.Automation automationAccounts、module、deployment()
上記リストには、「roleassign.bicep」というロール割り当てを実際に行うためのBicepファイルが別途必要だ。これについても前出のTech TIPSを参照していただきたい。
【Azure CLI】スケジュール付きでAutomationアカウントをデプロイする
以上のARMテンプレートからデプロイするには、「az deployment group create」コマンドを以下のように実行する(Automationアカウントのリソースグループは作成済みとする)。
az deployment group create -g <Automationアカウントのリソースグループ名> -f main.bicep -p VMName=<VMの名称> VMRG=<VMのリソースグループ名> VMStartTimeLocal=<起動時刻> VMStopTimeLocal=<シャットダウン時刻> automationAccountName=<Automationアカウント名> definedRoleId=<カスタムロールのGUID>
以上で、毎日決まった時刻に指定のVMを自動的に起動/シャットダウンするAutomationアカウントがデプロイできるはずだ。
【ポータル】作成したAutomationアカウントのスケジュールを確認する
作成したAutomationアカウントのスケジュールをAzureポータルで確認する場合、以下のようにAutomationアカウント画面の[プロセスオートメーション]−[Runbook]からたどっていく方がよい。[共有リソース]−[スケジュール]で表示されるスケジュールの詳細では、Runbookのスクリプトに渡すパラメーターを確認できないからだ。
■操作手順
- Azureポータルで対象のAutomationアカウントのページを開く
- 左側メニューの[プロセスオートメーション]−[Runbook]をクリック
- 右ペインに表示されたRunbook一覧で、対象のRunbookの名前をクリック
- 対象のRunbookのページが表示されたら、左側メニューの[リソース]−[スケジュール]をクリック
- 右ペインに表示されたスケジュール一覧で、確認したいスケジュールをクリック
- 右側に現れたブレードにスケジュールの詳細が表示されたら、説明や開始日時などが意図した通りに設定されているかどうかを確認する
Copyright© Digital Advantage Corp. All Rights Reserved.