다음을 통해 공유


튜토리얼: Automation에서 웹후크를 사용하여 사전 및 사후 이벤트 생성

적용 대상: ✔️ Windows VM ✔️ Linux VM ✔️ 온-프레미스 환경 ✔️ Azure VM ✔️ Azure Arc 지원 서버.

사전/사후 스크립트라고도 하는 사전 및 사후 이벤트를 사용하면 패치 설치 예약 전후에 사용자 정의 작업을 실행할 수 있습니다. 가장 일반적인 시나리오 중 하나는 VM(가상 머신)을 시작하고 중지하는 것입니다. 사전 이벤트를 사용하면 일정 패치 프로세스를 시작하기 전에 사전 패치 스크립트를 실행하여 VM을 시작할 수 있습니다. 일정 패치가 완료되고 서버가 다시 부팅되면 사후 패치 스크립트를 실행하여 VM을 안전하게 종료할 수 있습니다.

이 자습서에서는 웹후크를 사용하여 패치 예약 워크플로에서 VM을 시작하고 중지하기 위한 사전 및 사후 이벤트를 만드는 방법을 설명합니다.

이 자습서에서는 다음을 하는 방법을 알아볼 수 있습니다.

  • 필수 조건
  • Automation Runbook 만들기 및 게시
  • 웹후크 추가
  • 이벤트 구독 만들기

필수 조건

  1. PowerShell 7.2 Runbook을 사용하고 있는지 확인합니다.

  2. 관리 ID에 권한 할당 - 적절한 관리 ID에 권한을 할당할 수 있습니다. Runbook은 Automation 계정의 시스템이 할당한 관리 ID 또는 사용자가 할당한 관리 ID를 사용할 수 있습니다.

    포털 또는 PowerShell cmdlet을 사용하여 각 ID에 권한을 할당할 수 있습니다.

    권한을 할당하려면 Azure Portal을 사용하여 Azure 역할 할당의 단계를 따릅니다.


  1. Az.ResourceGraph 모듈을 가져오고 모듈이 모듈 버전 2.0.3을 사용하여 ThreadJob으로 업데이트되었는지 확인합니다.

Automation Runbook 만들기 및 게시

  1. Azure Portal에 로그인하고 Azure Automation 계정으로 이동합니다.

  2. Automation Runbook을 만들고 게시합니다.

  3. Azure Automation 업데이트 관리에서 사전 또는 사후 작업에 사용되던 Runbook을 사용하는 경우 컴퓨터에 대한 예기치 않은 영향과 유지 관리 실행 실패를 방지하려면 아래 단계를 따라야 합니다.

    1. Runbook의 경우 웹후크 페이로드를 구문 분석하여 Microsoft.Maintenance.PreMaintenanceEvent 또는 Microsoft.Maintenance.PostMaintenanceEvent 이벤트에서만 트리거되는지 확인합니다. 설계상 웹후크는 동일한 엔드포인트를 사용하여 다른 이벤트가 추가되면 다른 구독 이벤트에서 트리거됩니다.

      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  
      } 
      
    2. 업데이트 배포의 컴퓨터 목록에 대한 정보가 포함된 SoftwareUpdateConfigurationRunContext 매개 변수는 자동화 웹후크를 사용하는 동안 사전 또는 사후 이벤트에 사용할 때 사전 또는 사후 스크립트에 전달되지 않습니다. Azure Resource Graph에서 컴퓨터 목록을 쿼리하거나 스크립트에 컴퓨터 목록을 코딩할 수 있습니다.

      • Resource Graph 쿼리를 실행하고 컴퓨터를 시작하거나 중지하기 위해 스크립트에서 사용 중인 관리 ID에 적절한 역할과 권한이 부여되었는지 확인합니다.
      • 리소스 그래프 쿼리와 관련된 권한 확인
      • 가상 머신 기여자 역할을 참조하세요.
      • 아래 나열된 코드를 참조하세요.
    3. 웹후크 페이로드 참조

      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    
      }
      }
      
    4. 사용자 지정하려면 위 수정이 완료된 기존 스크립트를 사용하거나 다음 스크립트를 사용할 수 있습니다.

샘플 스크립트

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 
    } 
} 

웹후크 추가

위에 게시된 Runbook에 웹후크를 추가하고 웹후크 URL을 복사합니다.

참고 항목

URL을 다시 검색할 수 없으므로 웹후크를 만든 후에는 URL을 복사해야 합니다.

이벤트 구독 만들기

  1. Azure Portal에 로그인하고 Azure 업데이트 관리자로 이동합니다.

  2. 관리에서 컴퓨터, 유지 관리 구성을 선택합니다.

  3. 유지 관리 구성 페이지에서 구성을 선택합니다.

  4. 설정에서 이벤트를 선택합니다.

    이벤트 메뉴 옵션을 선택하는 옵션을 보여 주는 스크린샷.

  5. 사전/사후 유지 관리 이벤트를 만들려면 +이벤트 구독을 선택합니다.

    이벤트 구독을 선택하는 옵션을 보여 주는 스크린샷.

  6. 이벤트 구독 만들기 페이지에서 다음 세부 정보를 입력합니다.

    1. 이벤트 구독 세부 정보 섹션에 적절한 이름을 입력합니다.
    2. 스키마를 Event Grid 스키마로 유지합니다.
    3. 이벤트 유형 섹션에서 이벤트 유형으로 필터링합니다.
      1. 사전 이벤트를 보려면 사전 유지 관리 이벤트를 선택합니다.
        • 엔드포인트 세부 정보 섹션에서 웹후크 엔드포인트를 선택한 후 엔드포인트 구성을 선택합니다.
        • 이벤트를 트리거하려면 사전 이벤트 웹후크 URL과 같은 적절한 세부 정보를 제공합니다.
      2. 사후 이벤트를 보려면 사후 유지 관리 이벤트를 선택합니다.
        • 엔드포인트 세부 정보 섹션에서 웹후크 엔드포인트를 선택한 후 엔드포인트 구성을 선택합니다.
        • 이벤트를 트리거하려면 이벤트 후 웹후크 URL과 같은 적절한 세부 정보를 제공합니다. 이벤트 구독을 만드는 옵션을 보여 주는 스크린샷.
  7. 만들기를 실행합니다.

다음 단계