適用対象: ✔️ Windows VM ✔️ Linux VM ✔️ オンプレミス環境 ✔️ Azure Arc 対応サーバー。
メンテナンス前イベントとメンテナンス後イベントを使用して、スケジュールされたパッチインストールの前後にユーザー定義アクションを実行できます。 最も一般的なシナリオの 1 つは、仮想マシン (VM) の起動と停止です。 メンテナンス前イベントでは、スケジュールされた修正プログラムの適用プロセスを開始する前に、VM を起動するスクリプトを実行できます。 スケジュールされた修正プログラムの適用が完了し、サーバーが再起動されたら、スクリプトを実行して VM を安全にシャットダウンできます。
このチュートリアルでは、Webhook を使用して、スケジュールされたパッチ ワークフローで VM を開始および停止するためのメンテナンス前イベントとメンテナンス後イベントを作成する方法について説明します。
このチュートリアルでは、次の操作を行います。
- Azure Automation Runbook を作成して発行します。
- Webhook を追加します。
- イベント サブスクリプションを作成します。
前提条件
PowerShell 7.4 Runbook を使用していることを確認します。
適切なマネージド ID にアクセス許可を割り当てます。 Runbook では、Automation アカウントのシステム割り当てマネージド ID またはユーザー割り当てマネージド ID を使用できます。
次のスクリプトの例 (VM の起動と停止) には、仮想マシン共同作成者ロールまたはこれらの特定のアクセス許可を持つカスタム ロールが必要です。
- Microsoft.Compute/virtualMachines/start/action
- Microsoft.Compute/virtualMachines/deallocate/action
- Microsoft.Compute/virtualMachines/restart/action (仮想マシンの再起動アクション)
- Microsoft.Compute/virtualMachines/powerOff/action
Azure portal または Azure PowerShell コマンドレットを使用して、各 ID にアクセス許可を割り当てることができます。
アクセス許可を割り当てるには、「 Azure portal を使用して Azure ロールを割り当てる」の手順に従います。
-
Az.ResourceGraphモジュールをインポートします。 モジュールバージョン 2.0.3 でモジュールが ThreadJob に更新されていることを確認します。
オートメーションのランブックを作成して公開する
Azure portal にサインインし、Azure Automation アカウントに移動します。
Azure Automation Update Management でメンテナンス 前およびメンテナンス後のタスク に Runbook を使用した場合は、次の手順を使用して、マシンへの予期しない影響とメンテナンスの実行の失敗を回避することが重要です。
Runbook の場合は、webhook ペイロードを解析して、
Microsoft.Maintenance.PreMaintenanceEventまたはMicrosoft.Maintenance.PostMaintenanceEventイベントでのみトリガーされるようにします。 設計上、他のイベントが同じエンドポイントで追加された場合、Webhook は他のサブスクリプション イベントでトリガーされます。Azure Event Grid イベント スキーマに関する情報を参照してください。
次のコードを参照してください。
param ( [Parameter(Mandatory=$false)] [object] $WebhookData ) $notificationPayload = ConvertFrom-Json -InputObject $WebhookData.RequestBody $eventType = $notificationPayload[0].eventType if ($eventType -ne "Microsoft.Maintenance.PreMaintenanceEvent" -and $eventType –ne "Microsoft.Maintenance.PostMaintenanceEvent" ) { Write-Output "Webhook not triggered as part of pre or post patching for maintenance run" return }
SoftwareUpdateConfigurationRunContext パラメーターには、更新プログラムの展開内のコンピューターの一覧に関する情報が含まれています。 Automation Webhook を使用している際に、メンテナンス前またはメンテナンス後のイベントでスクリプトを利用する場合、スクリプトには渡されません。 該当するマシンを知るには、Azure Resource Graph に対してクエリを実行する方法や、スクリプト内のコードにマシン一覧を保持しておく方法があります。
Resource Graph クエリの実行とマシンの起動および停止を確実に実行できるよう、スクリプトで使用するマネージド ID に適切なロールとアクセス許可が付与されていることを確認してください。
Resource Graph クエリに関連するアクセス許可を参照してください。
仮想マシン共同作成者ロールを参照してください。
Webhook ペイロードを参照してください。
次のコードを参照してください。
param ( [Parameter(Mandatory=$false)] [object] $WebhookData ) Connect-AzAccount -Identity # Install the Resource Graph module from PowerShell Gallery # Install-Module -Name Az.ResourceGraph $notificationPayload = ConvertFrom-Json -InputObject $WebhookData.RequestBody $maintenanceRunId = $notificationPayload[0].data.CorrelationId $resourceSubscriptionIds = $notificationPayload[0].data.ResourceSubscriptionIds if ($resourceSubscriptionIds.Count -gt 0) { Write-Output "Querying ARG to get machine details[MaintenanceRunId=$maintenanceRunId][ResourceSubscriptionIdsCount=$($resourceSubscriptionIds.Count)]" $argQuery = @"maintenanceresources | where type =~ 'microsoft.maintenance/applyupdates' | where properties.correlationId =~ '$($maintenanceRunId)' | where id has '/providers/microsoft.compute/virtualmachines/' | project id, resourceId = tostring(properties.resourceId) | order by id asc "@ Write-Output "Arg Query Used: $argQuery" $allMachines = [System.Collections.ArrayList]@() $skipToken = $null $res = Search-AzGraph -Query $argQuery -First 1000 -SkipToken $skipToken -Subscription $resourceSubscriptionIds $skipToken = $res.SkipToken $allMachines.AddRange($res.Data) } while ($skipToken -ne $null -and $skipToken.Length -ne 0) if ($allMachines.Count -eq 0) { Write-Output "No Machines were found." break } }
カスタマイズするには、前の変更で既存のスクリプトを使用するか、次のスクリプトを使用します。
サンプルのスクリプト
param
(
[Parameter(Mandatory=$false)]
[object] $WebhookData
)
Connect-AzAccount -Identity
# Install the Resource Graph module from PowerShell Gallery
# Install-Module -Name Az.ResourceGraph
$notificationPayload = ConvertFrom-Json -InputObject $WebhookData.RequestBody
$eventType = $notificationPayload[0].eventType
if ($eventType -ne "Microsoft.Maintenance.PreMaintenanceEvent") {
Write-Output "Webhook not triggered as part of pre-patching for maintenance run"
return
}
$maintenanceRunId = $notificationPayload[0].data.CorrelationId
$resourceSubscriptionIds = $notificationPayload[0].data.ResourceSubscriptionIds
if ($resourceSubscriptionIds.Count -eq 0) {
Write-Output "Resource subscriptions are not present."
break
}
Write-Output "Querying ARG to get machine details [MaintenanceRunId=$maintenanceRunId][ResourceSubscriptionIdsCount=$($resourceSubscriptionIds.Count)]"
$argQuery = @"
maintenanceresources
| where type =~ 'microsoft.maintenance/applyupdates'
| where properties.correlationId =~ '$($maintenanceRunId)'
| where id has '/providers/microsoft.compute/virtualmachines/'
| project id, resourceId = tostring(properties.resourceId)
| order by id asc
"@
Write-Output "Arg Query Used: $argQuery"
$allMachines = [System.Collections.ArrayList]@()
$skipToken = $null
do
{
$res = Search-AzGraph -Query $argQuery -First 1000 -SkipToken $skipToken -Subscription $resourceSubscriptionIds
$skipToken = $res.SkipToken
$allMachines.AddRange($res.Data)
} while ($skipToken -ne $null -and $skipToken.Length -ne 0)
if ($allMachines.Count -eq 0) {
Write-Output "No Machines were found."
break
}
$jobIDs= New-Object System.Collections.Generic.List[System.Object]
$startableStates = "stopped" , "stopping", "deallocated", "deallocating"
$allMachines | ForEach-Object {
$vmId = $_.resourceId
$split = $vmId -split "/";
$subscriptionId = $split[2];
$rg = $split[4];
$name = $split[8];
Write-Output ("Subscription Id: " + $subscriptionId)
$mute = Set-AzContext -Subscription $subscriptionId
$vm = Get-AzVM -ResourceGroupName $rg -Name $name -Status -DefaultProfile $mute
$state = ($vm.Statuses[1].DisplayStatus -split " ")[1]
if($state -in $startableStates) {
Write-Output "Starting '$($name)' ..."
$newJob = Start-ThreadJob -ScriptBlock { param($resource, $vmname, $sub) $context = Set-AzContext -Subscription $sub; Start-AzVM -ResourceGroupName $resource -Name $vmname -DefaultProfile $context} -ArgumentList $rg, $name, $subscriptionId
$jobIDs.Add($newJob.Id)
} else {
Write-Output ($name + ": no action taken. State: " + $state)
}
}
$jobsList = $jobIDs.ToArray()
if ($jobsList)
{
Write-Output "Waiting for machines to finish starting..."
Wait-Job -Id $jobsList
}
foreach($id in $jobsList)
{
$job = Get-Job -Id $id
if ($job.Error)
{
Write-Output $job.Error
}
}
Webhook の追加
上記の発行済み Runbook に Webhook を追加し、Webhook URL をコピーします。
Note
Webhook を作成した後は、必ず URL をコピーしてください。 URL を再度取得することはできません。
イベント サブスクリプションの作成
Azure portal にサインインし、[Azure Update Manager] に移動します。
[ 管理] で、[ マシン>メンテナンス構成] を選択します。
[ メンテナンス構成 ] ウィンドウで、構成を選択します。
[設定] で、[イベント] を選択します。
[+イベント サブスクリプション] を選択して、メンテナンス前またはメンテナンス後のイベントを作成します。
[ イベント サブスクリプションの作成 ] ウィンドウの [ イベント サブスクリプションの詳細 ] セクションで、適切な名前を指定します。 スキーマは Event Grid スキーマのままにします。
[ イベントの種類] セクションの [ フィルターからイベントの種類] で、[ メンテナンス前イベント ] または [ メンテナンス後イベント] を選択します。
[ エンドポイントの詳細 ] セクションで、 Web Hook エンドポイントを選択し、[ エンドポイントの構成] を選択します。
イベントをトリガーするメンテナンス前またはメンテナンス後のイベントの webhook URL など、適切な詳細を指定します。
[作成]を選択します