次の方法で共有


チュートリアル: Azure Functions を使用して事前イベントと事後イベントを作成する

適用対象: ✔️ Windows VMs ✔️ Linux VM ✔️ オンプレミス環境 ✔️ Azure Arc 対応サーバー。

このチュートリアルでは、スケジュールされたパッチ適用ワークフローの中で VM の起動と停止を行う事前および事後イベントを、Azure Functions を使用して作成する方法について説明します。

このチュートリアルでは、次の作業を行う方法について説明します。

  • 前提条件
  • Function App を作成する
  • 関数を作成する
  • イベント サブスクリプションの作成

前提条件

  1. PowerShell 7.2 Runbook を使用していることを確認します。

  2. マネージド ID にアクセス許可を割り当てます。適切な マネージド ID に対して割り当て操作を実行してください。 Runbook では、Automation アカウントのシステム割り当てマネージド ID またはユーザー割り当てマネージド ID のいずれかを使用できます。

    個々の ID に対するアクセス許可の割り当て操作は、以下のようにポータルまたは PowerShell コマンドレットで実行できます。

    Azure portal を使用して Azure ロールを割り当てる」の手順に従ってアクセス許可を割り当てます。


  1. Az.ResourceGraph モジュールをインポートして、このモジュールを、確実にモジュール バージョン 2.0.3 の ThreadJob に更新します。

Function App を作成する

  1. 関数アプリを作成する手順に従います。

  2. 関数アプリを作成したら、リソースに移動し、次の手順に従って依存関係を確実に読み込みます。

    Note

    依存関係をロードする必要があるのは最初の 1 回だけです。

    1. [Function App] で、[アプリ ファイル] を選択します。

    2. host.json の下で、ManagedDependecy を有効にして True とし、requirements.psd1 を選択します。

    3. requirements.psd1 の下に、次のコードを貼り付けます。

       @{
       'Az'='5.*' 
       'Az.ResourceGraph'='0.13.0' 
       'Az.Resources'='6.*' 
       'ThreadJob' = '2.*'
       }
      
    4. [保存] を選択します。

  3. [概要] タブから関数アプリを再起動して、requirements.psd1 ファイルに記述されている依存関係を読み込みます。

関数を作成する

  1. 関数アプリを作成したら、[リソース] に移動し、[概要] で、[Azure portal で作成] を選択します。

  2. [関数の作成] ウィンドウで、次の項目を選択します。

    1. [開発環境] プロパティに対して、[ポータルで開発] を選択します
    2. [テンプレートの選択] で、[Event Grid] を選択します。
    3. [テンプレートの詳細] で、[新しい関数] に名前を入力して、[作成] を選択します。 関数の作成時に選択すべきオプションを示すスクリーンショット。
  3. [Event Grid] 関数の左側のメニューから [コードとテスト] を選択し、次のコードを貼り付けて [保存] を選択します。

    # Make sure that we are using eventGridEvent for parameter binding in Azure function.
    param($eventGridEvent, $TriggerMetadata)
    
    Connect-AzAccount -Identity
    
    # Install the Resource Graph module from PowerShell Gallery
    # Install-Module -Name Az.ResourceGraph
    
    $maintenanceRunId = $eventGridEvent.data.CorrelationId
    $resourceSubscriptionIds = $eventGridEvent.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
        }
    }
    
  4. 左側のメニューから [統合] を選択し、[トリガー] の下にある [イベント トリガー パラメーター名] を編集します。 [コードとテスト] ウィンドウで指定したのと同じパラメーター名を使用します。 この例では、パラメーターは eventGridEvent です。

    パラメーター eventGridEvent を示すスクリーンショット。

  5. [保存] を選びます。

イベント サブスクリプションの作成

  1. Azure portal にサインインし、[Azure Update Manager] に移動します。
  2. [管理] で、[マシン][メンテナンス構成] の順に選択します。
  3. [メンテナンス構成] ページで、構成を選択します。
  4. [設定] で、[イベント] を選択します。
  5. [+イベント サブスクリプション] を選択して、メンテナンス前とメンテナンス後のイベントを作成します。
  6. [イベント サブスクリプションの作成] ページで、次の詳細を入力します:
    1. [イベント サブスクリプションの詳細] セクションで、適切な名前を指定します。
    2. スキーマは Event Grid スキーマのままにします。
    3. [イベントの種類] セクションで、[イベントの種類のフィルター] を指定します。
      1. 事前イベントの場合は、[メンテナンス前イベント] を選択します。
        • [エンドポイントの詳細] セクションで、[Azure Function] エンドポイントを選択し、[構成とエンドポイント] を選択します。
        • リソース グループや、イベントをトリガーする関数アプリなど、適切な詳細情報を指定します。
      2. 事後イベントの場合は、[メンテナンス後イベント] を選択します。
        • [エンドポイントの詳細] セクションで、[Azure Function] エンドポイントを選択し、[構成とエンドポイント] を選択します。
        • リソース グループや、イベントをトリガーする関数アプリなど、適切な詳細情報を指定します。
  7. [作成] を選択します

また、Azure Storage アカウントとイベント ハブを使用して、イベントの格納、送信、受信を行うこともできます。 イベント ハブの作成方法と、ストレージ キューについて詳細を確認してください。

次のステップ