Partilhar via


Tutorial: Criar eventos pré-e pós-manutenção usando o Azure Functions

Aplica-se a: ✔️ VMs do Windows ✔️ VMs do Linux ✔️ VMs de Ambiente Local ✔️ VMs do Azure ✔️ Servidores habilitados para Azure Arc.

Este tutorial explica como criar eventos pré-manutenção e pós-manutenção para iniciar e parar uma máquina virtual (VM) num fluxo de trabalho de patch agendado, utilizando o Azure Functions.

Neste tutorial, irá aprender a:

  • Crie um aplicativo de função.
  • Crie uma função.
  • Crie uma subscrição para o evento.

Pré-requisitos

  1. Certifica-te de que estás a usar um runbook do PowerShell 7.4 .

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

    Os seguintes exemplos de scripts (VMs de início e paragem) requerem o papel de Contribuidor da Máquina Virtual ou um papel personalizado com estas permissões específicas:

    • Microsoft.Compute/virtualMachines/start/action
    • Microsoft.Compute/virtualMachines/deslocalizar/ação
    • Microsoft.Compute/máquinas virtuais/reiniciar/ação
    • Microsoft.Compute/virtualMachines/powerOff/action

    Pode usar o portal Azure ou os cmdlets Azure PowerShell para atribuir permissões a cada identidade:

    Para atribuir permissões, siga os passos em Atribuir funções Azure usando o portal Azure.


  1. Importa o Az.ResourceGraph módulo. Certifique-se de que o módulo está atualizado para ThreadJob com a versão 2.0.3 do módulo.

Criar uma aplicação de funções

  1. Siga os passos para criar uma aplicação funcional.

  2. Vai ao recurso e carrega as dependências usando os seguintes passos.

    Nota

    Tens de carregar as dependências apenas à primeira. Se as dependências do PowerShell não estiverem a carregar, verifique as versões mais recentes de Az e Az.ResourceGraph.

    1. Para Function App, selecione ficheiros App.

    2. Em host.json, defina Managed Dependecy para True e selecione requirements.psd1.

    3. Em requirements.psd1, cole o seguinte código:

      @{
      'Az'='12.*' 
      'Az.ResourceGraph'='1.0.0' 
      'Az.Resources'='6.*' 
      'ThreadJob' = '2.*'
      }
      
    4. Selecione Guardar.

  3. Reinicie a aplicação de função na guia Visão geral para carregar as dependências referidas no ficheiro requirements.psd1.

Criar uma função

  1. Depois de criares a aplicação de funções, vai ao recurso, vai a Visão Geral e depois seleciona Criar no portal Azure.

  2. No painel de funções Criar , faça as seguintes seleções:

    1. Em Selecionar ambiente de desenvolvimento, para Ambiente de desenvolvimento, selecione Desenvolver no portal.

    2. Em Selecionar um modelo, selecione grelha de eventos.

    3. Em Detalhes do Modelo, para Nova Função, selecione o nome. Em seguida, selecione Criar.

      Captura de ecrã que mostra seleções para criar uma função.

  3. No painel de funções da grelha de eventos , selecione Code+Test no menu esquerdo. Cola o código seguinte e depois seleciona Guardar.

    # Make sure that you're using eventGridEvent for parameter binding in the 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. No menu esquerdo, selecione Integração. Para Trigger, introduza o valor do nome do parâmetro Event Trigger . Use o mesmo nome de parâmetro fornecido na janela Code+Test . No exemplo, o parâmetro é eventGridEvent.

    Captura de ecrã que mostra a entrada do nome de um parâmetro para um gatilho de evento.

  5. Selecione Guardar.

Criar uma subscrição de evento

  1. Inicie sessão no portal do Azure e aceda ao Gestor de Atualizações do Azure.

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

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

  4. Em Configurações, selecione Eventos.

  5. Selecione +Subscrição de Evento para criar um evento pré-manutenção ou pós-manutenção.

  6. No painel de Criar Subscrição de Evento , na secção Detalhes de Subscrição de Evento , indique um nome apropriado. Mantenha o esquema como Esquema de Grade de Eventos.

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

  8. Na secção Detalhes do Endpoint , selecione o endpoint Azure Function e depois selecione Configurar um endpoint.

  9. Forneça os detalhes apropriados, como o grupo de recursos e a aplicação de funções para desencadear o evento.

  10. Selecione Criar.

Também pode usar contas Azure Storage e um hub de eventos para armazenar, enviar e receber eventos. Para mais informações, consulte os quickstarts sobre como criar uma fila no Azure Storage e criar um hub de eventos usando o portal Azure.