Compartilhar via


Tutorial: Criar eventos de pré-manutenção e pós-manutenção usando um webhook com runbooks de Automação

Aplica-se a: ✔️ Máquinas virtuais Windows ✔️ Máquinas virtuais Linux ✔️ Ambiente local ✔️ Máquinas virtuais do Azure ✔️ Servidores habilitados para Azure Arc.

Você pode usar eventos de pré-manutenção e pós-manutenção para executar ações definidas pelo usuário antes e depois da instalação de patch agendada. Um dos cenários mais comuns é iniciar e parar uma VM (máquina virtual). Com eventos de pré-manutenção, você pode executar um script para iniciar a VM antes de iniciar o processo de aplicação de patch agendado. Depois que a aplicação de patch agendada for concluída e o servidor for reinicializado, você poderá executar um script para desligar a VM com segurança.

Este tutorial explica como criar eventos de pré-manutenção e pós-manutenção para iniciar e parar uma VM em um fluxo de trabalho de patch agendado usando um webhook.

Neste tutorial, você:

  • Crie e publique um runbook do Azure Automation.
  • Adicione webhooks.
  • Crie uma assinatura de evento.

Pré-requisitos

  1. Verifique se você está usando um runbook do PowerShell 7.4 .

  2. Atribua permissões à identidade gerenciada apropriada. O runbook pode usar a identidade gerenciada atribuída pelo sistema da conta de Automação ou uma identidade gerenciada atribuída ao usuário.

    Os exemplos de script a seguir (iniciando e interrompendo VMs) exigem a função Colaborador de Máquina Virtual ou uma função personalizada com estas permissões específicas:

    • Microsoft.Compute/virtualMachines/start/action
    • Microsoft.Compute/virtualMachines/deallocate/action
    • Microsoft.Compute/virtualMachines/restart/action
    • Microsoft.Compute/virtualMachines/powerOff/action

    Você pode usar o portal do Azure ou os cmdlets do Azure PowerShell para atribuir permissões a cada identidade:

    Para atribuir permissões, siga as etapas em Atribuir funções do Azure usando o portal do Azure.


  1. Importe o Az.ResourceGraph módulo. Verifique se o módulo foi atualizado para o ThreadJob com o módulo versão 2.0.3.

Criar e publicar um runbook de automação

  1. Entre no portal do Azure e acesse sua conta de Automação do Azure .

  2. Crie e publique um runbook de automação.

  3. Se você usou runbooks para tarefas de pré-manutenção e pós-manutenção no Gerenciamento de Atualizações de Automação do Azure, é fundamental que você use as seguintes etapas para evitar um impacto inesperado em seus computadores e execuções de manutenção com falha:

    1. Para seus runbooks, analise a carga útil do webhook para garantir que ele dispare somente em eventos Microsoft.Maintenance.PreMaintenanceEvent ou Microsoft.Maintenance.PostMaintenanceEvent. Por padrão, os webhooks são acionados em outros eventos de assinatura, caso qualquer outro evento seja adicionado com o mesmo endpoint.

    2. O parâmetro SoftwareUpdateConfigurationRunContext contém informações sobre listas de computadores na implantação de atualização. Ele não será passado para os scripts quando você os usar para eventos de pré-manutenção ou pós-manutenção ao usar um webhook de Automação. Você pode consultar a lista de computadores do Azure Resource Graph ou ter a lista de computadores codificados nos scripts.

      • Verifique se as funções e permissões adequadas são concedidas às identidades gerenciadas que você está usando no script, para executar consultas do Resource Graph e para iniciar ou parar computadores.

      • Consulte as permissões relacionadas às consultas do Resource Graph.

      • Consulte a função Colaborador da Máquina Virtual.

      • Veja o payload do webhook.

      • Consulte o seguinte código:

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

Para personalizar, você pode usar seus scripts existentes com as modificações anteriores ou usar os scripts a seguir.

Scripts de exemplo

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

Adicionar webhooks

Adicione webhooks aos runbooks publicados anteriormente e copie as URLs do webhook.

Observação

Copie a URL depois de criar um webhook. Não é possível recuperar a URL novamente.

Criar uma assinatura de evento

  1. Entre no portal do Azure e vá para Azure Update Manager.

  2. Em Gerenciar, selecioneConfiguração de Manutenção de >.

  3. No painel Configuração de Manutenção , selecione a configuração.

  4. Em Configurações, selecione Eventos.

    Captura de tela que mostra a opção de menu para eventos.

  5. Selecione +Assinatura de Evento para criar um evento de manutenção prévia ou manutenção posterior.

    Captura de tela que mostra assinaturas de evento com a opção de criar uma assinatura de evento.

  6. No painel Criar Assinatura de Evento , na seção Detalhes da Assinatura do Evento , forneça um nome apropriado. Mantenha o esquema como Esquema da Grade de Eventos.

  7. Na seção Tipos de Eventos , para Filtrar para Tipos de Eventos, selecione Evento de Pré-Manutenção ou Evento pós-manutenção.

  8. Na seção Detalhes do Ponto de Extremidade , selecione o ponto de extremidade do Web Hook e, em seguida, selecione Configurar um ponto de extremidade.

  9. Forneça os detalhes apropriados, como a URL de webhook para o evento de pré-manutenção ou pós-manutenção, a fim de disparar o evento.

    Captura de tela que mostra as opções para criar assinaturas de evento.

  10. Selecione Criar.