Partager via


Tutoriel : Créer des événements de pré-maintenance et de post-maintenance à l’aide d’Azure Functions

S’applique à : ✔️ Machines virtuelles Windows ✔️ Machines virtuelles Linux ✔️ Environnement local ✔️ Machines virtuelles Azure ✔️ Serveurs compatibles avec Azure Arc.

Ce tutoriel explique comment créer des événements de pré-maintenance et de post-maintenance pour démarrer et arrêter une machine virtuelle dans un workflow de correctif planifié à l’aide d’Azure Functions.

Dans ce tutoriel, vous allez apprendre à :

  • Créez une application de fonction.
  • Créez une fonction.
  • Créez un abonnement aux événements.

Prérequis

  1. Assurez-vous que vous utilisez un runbook PowerShell 7.4.

  2. Affectez des autorisations à l’identité managée appropriée. Le runbook peut utiliser l’identité managée attribuée par le système du compte Automation ou une identité managée attribuée par l’utilisateur.

    Les exemples de script suivants (démarrage et arrêt de machines virtuelles) nécessitent le rôle Contributeur de machine virtuelle ou un rôle personnalisé avec ces autorisations spécifiques :

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

    Vous pouvez utiliser le portail Azure ou les applets de commande Azure PowerShell pour attribuer des autorisations à chaque identité :

    Pour attribuer des autorisations, suivez les étapes décrites dans Affecter des rôles Azure à l’aide du portail Azure.


  1. Importez le Az.ResourceGraph module. Vérifiez que le module est mis à jour vers ThreadJob avec le module version 2.0.3.

Créer une application de fonction

  1. Suivez les étapes pour créer une application de fonction.

  2. Accédez à la ressource et chargez les dépendances en procédant comme suit.

    Remarque

    Vous devez charger les dépendances uniquement la première fois. Si les dépendances PowerShell ne sont pas chargées, vérifiez les dernières versions de Az et Az.ResourceGraph.

    1. Pour l’application de fonction, sélectionnez Fichiers d’application.

    2. Sous host.json, définissez ManagedDependecy sur True et sélectionnez requirements.psd1.

    3. Sous requirements.psd1, collez le code suivant :

      @{
      'Az'='12.*' 
      'Az.ResourceGraph'='1.0.0' 
      'Az.Resources'='6.*' 
      'ThreadJob' = '2.*'
      }
      
    4. Cliquez sur Enregistrer.

  3. Redémarrez l’application de fonction à partir de l’onglet Vue d’ensemble pour charger les dépendances mentionnées dans le fichier requirements.psd1.

Créer une fonction

  1. Après avoir créé l’application de fonction, accédez à la ressource, accédez à Vue d’ensemble, puis sélectionnez Créer dans le portail Azure.

  2. Dans le volet Créer une fonction , effectuez les sélections suivantes :

    1. Sous Sélectionner un environnement de développement, pour l’environnement de développement, sélectionnez Développer dans le portail.

    2. Sous Sélectionner un modèle, sélectionnez Event Grid.

    3. Sous Détails du modèle, pour Nouvelle fonction, sélectionnez le nom. Sélectionnez ensuite Créer.

      Capture d’écran montrant les sélections pour la création d’une fonction.

  3. Dans le volet de fonction Event Grid , sélectionnez Code+Test dans le menu de gauche. Collez le code suivant, puis sélectionnez Enregistrer.

    # 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. Dans le menu de gauche, sélectionnez Intégration. Pour Déclencheur, entrez la valeur du nom du paramètre de déclenchement d'événement. Utilisez le même nom de paramètre donné dans la fenêtre Code + Test. Dans l’exemple, le paramètre est eventGridEvent.

    Capture d’écran montrant l’entrée d’un nom de paramètre pour un déclencheur d’événement.

  5. Cliquez sur Enregistrer.

Créer un abonnement d’événement

  1. Connectez-vous au Portail Microsoft Azure et accédez à Azure Update Manager.

  2. Sous Gérer, sélectionnezConfiguration de maintenance>.

  3. Dans le volet Configuration de maintenance, sélectionnez la configuration.

  4. Sous Paramètres, sélectionnez Événements.

  5. Sélectionnez +Abonnement aux événements pour créer un événement de pré-maintenance ou de post-maintenance.

  6. Dans le volet Créer un abonnement aux événements, dans la section Détails de l’abonnement aux événements, indiquez un nom approprié. Conservez Schéma Event Grid comme schéma.

  7. Dans la section Types d’événements, pour filtrer les types d’événements, sélectionnez Événement de pré maintenance ou après maintenance.

  8. Dans la section Détails du point de terminaison , sélectionnez le point de terminaison de fonction Azure , puis configurez un point de terminaison.

  9. Fournissez les détails appropriés, tels que le groupe de ressources et l’application de fonction pour déclencher l’événement.

  10. Sélectionnez Créer.

Vous pouvez également utiliser des comptes stockage Azure et un hub d’événements pour stocker, envoyer et recevoir des événements. Pour plus d’informations, consultez les guides de démarrage rapide sur la création d’une file d’attente dans stockage Azure et la création d’un hub d’événements à l’aide du portail Azure.