Partager via


Définir l’ordre de démarrage des machines virtuelles DevTest Labs avec Azure Automation

Cet article explique comment démarrer des machines virtuelles DevTest Labs dans un ordre spécifique à l’aide d’un runbook PowerShell dans Azure Automation. Le script PowerShell utilise des étiquettes sur les machines virtuelles du lab, ce qui vous permet de changer l’ordre de démarrage sans avoir à modifier le script.

La fonctionnalité de démarrage automatique de DevTest Labs peut configurer des machines virtuelles de lab pour qu’elles démarrent automatiquement à une heure spécifiée. Toutefois, il peut arriver que vous souhaitiez que les machines virtuelles de lab démarrent dans un ordre spécifique. Par exemple, si une machine virtuelle JumpBox dans un lab est le point d’accès aux autres machines virtuelles, elle doit démarrer avant les autres machines virtuelles.

Prérequis

  • Créez et appliquez une étiquette nommée StartupOrder à toutes les machines virtuelles de lab avec une valeur de démarrage appropriée, comprise entre 0 et 10. Désignez les machines qui n’ont pas besoin de démarrer avec la valeur -1.

  • Créez un compte Azure Automation en suivant les instructions de l’article Créer un compte Azure Automation autonome. Choisissez l’option Compte d’identification lorsque vous créez le compte.

Créer le runbook PowerShell

  1. Dans la page Vue d’ensemble du compte Automation, sélectionnez Runbooks dans le menu de gauche.
  2. Dans la page Runbooks, sélectionnez Créer un runbook.
  3. Suivez les instructions fournies dans Créer un runbook PowerShell Automation avec une identité managée pour créer un runbook PowerShell. Remplissez le runbook avec le script PowerShell suivant.

Préparer le script PowerShell

Le script suivant prend comme paramètres le nom de l’abonnement et le nom du lab. Le script obtient toutes les machines virtuelles du lab, puis analyse les informations de leurs étiquettes pour créer une liste des noms des machines virtuelles et de leur ordre de démarrage. Le script parcourt la liste dans l’ordre et démarre les machines virtuelles.

S’il existe plusieurs machines virtuelles avec un même numéro d’ordre, elles démarrent de façon asynchrone via des travaux PowerShell. Les machines virtuelles qui n’ont pas d’étiquette ont leur valeur de démarrage définie sur 10, et elles démarrent en dernier par défaut. Le script ignore toutes les machines virtuelles dont les valeurs d’étiquette ne sont pas comprises entre 0 et 10.

#Requires -Version 3.0
#Requires -Module AzureRM.Resources

param
(
    [Parameter(Mandatory=$false, HelpMessage="Name of the subscription that has the lab")]
    [string] $SubscriptionName,

    [Parameter(Mandatory=$false, HelpMessage="Lab name")]
    [string] $LabName
)

# Connect and add the appropriate subscription
$Conn = Get-AutomationConnection -Name AzureRunAsConnection

Add-AzureRMAccount -ServicePrincipal -Tenant $Conn.TenantID -ApplicationID $Conn.ApplicationId -Subscription $SubscriptionName -CertificateThumbprint $Conn.CertificateThumbprint

# Find the lab
$dtLab = Find-AzResource -ResourceType 'Microsoft.DevTestLab/labs' -ResourceNameEquals $LabName

# Get the VMs
$dtlAllVms = New-Object System.Collections.ArrayList
$AllVMs = Get-AzResource -ResourceId "$($dtLab.ResourceId)/virtualmachines" -ApiVersion 2016-05-15

# Get the StartupOrder tag. If missing, set to start up last (10).
ForEach ($vm in $AllVMs) {
    if ($vm.Tags) {
        if ($vm.Tags['StartupOrder']) {
            $startupValue = $vm.Tags['StartupOrder']
        } else {
            $startupValue = 10
        }
        } else {
            $startupValue = 10
        }
        $dtlAllVms.Add(@{$vm.Name = $startupValue}) > $null
}

# Setup for the async multiple vm start

# Save profile
$profilePath = Join-Path $env:Temp "profile.json"
If (Test-Path $profilePath){
    Remove-Item $profilePath
}
Save-AzContext -Path $profilePath

# Job to start VMs asynch
$startVMBlock = {
    Param($devTestLab,$vmToStart,$profilePath)
    Import-AzContext -Path ($profilePath)
    Invoke-AzResourceAction `
        -ResourceId "$($devTestLab.ResourceId)/virtualmachines/$vmToStart" `
        -Action Start `
        -Force
    Write-Output "Started: $vmToStart"
}

$current = 0
# Start in order from 0 to 10

While ($current -le 10) {
# Get the VMs in the current stage
    $tobeStarted = $null
    $tobeStarted = $dtlAllVms | Where-Object { $_.Values -eq $current}
    if ($tobeStarted.Count -eq 1) {
        # Run sync – jobs not necessary for a single VM
        $returnStatus = Invoke-AzResourceAction `
                -ResourceId "$($dtLab.ResourceId)/virtualmachines/$($tobeStarted.Keys)" `
                -Action Start `
                -Force
        Write-Output "$($tobeStarted.Keys) status: $($returnStatus.status)"
    } elseif ($tobeStarted.Count -gt 1) {
        # Start multiple VMs async
        $jobs = @()
        Write-Output "Start Jobs start: $(Get-Date)"
        
        # Jobs
        $jobs += Start-Job -ScriptBlock $startVMBlock -ArgumentList $dtLab, $($singlevm.Keys), $profilePath
        Write-Output "Start Jobs end: $(Get-Date)"
    }

    # Get results from all jobs
    if($jobs.Count -ne 0) {
        Write-Output "Receive Jobs start: $(Get-Date)"
        foreach ($job in $jobs){
            $jobResult = Receive-Job -Job $job -Wait | Write-Output
        }
        Remove-Job -Job $jobs -Force
    }
    else
    {
        Write-Output "Information: No jobs available"
    }
}

Exécuter le script

  • Pour exécuter ce script quotidiennement, créez une planification dans le compte Automation et liez la planification au runbook.

  • Dans un scénario d’entreprise qui a plusieurs abonnements avec plusieurs labs, vous pouvez stocker les informations des paramètres pour différents labs et abonnements dans un fichier. Passez le fichier au script au lieu de passer les paramètres individuels.

  • Cet exemple utilise Azure Automation pour exécuter le script PowerShell, mais vous pouvez également utiliser d’autres options, comme un pipeline de build/mise en production.

Étapes suivantes