Поделиться через


Определение порядка запуска для виртуальных машин DevTest Lab с помощью службы автоматизации Azure

В этой статье описывается, как запустить виртуальные машины DevTest Labs в определенном порядке с помощью модуля Runbook PowerShell в службе автоматизации Azure. Сценарий PowerShell использует теги на виртуальных машинах в лаборатории, чтобы вы могли менять порядок загрузки без необходимости изменения сценария.

Функция автозапуска в DevTest Labs позволяет настроить автоматический запуск виртуальных машин в указанное время. Тем не менее иногда может потребоваться запустить виртуальные машины в определенной последовательности. Например, если виртуальная машина Jumpbox в лаборатории является точкой доступа к другим виртуальным машинам, виртуальная машина Jumpbox должна запускаться до других виртуальных машин.

Предварительные требования

Создание модуля Runbook PowerShell

  1. На странице Обзор учетной записи службы автоматизации в меню слева выберите Модули Runbook.
  2. На странице Модули Runbook выберите Добавить Runbook.
  3. Чтобы создать модуль Runbook PowerShell, следуйте инструкциям в статье Создание модуля Runbook службы автоматизации PowerShell с помощью управляемого удостоверения. Заполните модуль Runbook следующим сценарием PowerShell.

Подготовка сценария PowerShell

Следующий сценарий принимает имя подписки и имя лаборатории в качестве параметров. Сценарий получает все виртуальные машины в лаборатории, а затем анализирует сведения о теге, чтобы создать список имен виртуальных машин и их порядок запуска. Сценарий проходит список по порядку и запускает виртуальные машины.

Если в определенном порядковом номере есть несколько виртуальных машин, они запускаются асинхронно с помощью заданий PowerShell. Для виртуальных машин, у которых нет тега, значение запуска равно 10 и по умолчанию они запускаются последними. Скрипт игнорирует все виртуальные машины, имеющие значения тегов, отличные от 0-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"
    }
}

Выполнение скрипта

  • Чтобы запускать этот сценарий ежедневно, создайте расписание в учетной записи службы автоматизации и свяжите расписание с модулем Runbook.

  • В корпоративном сценарии, в котором есть несколько подписок с несколькими лабораториями, можно хранить сведения о параметрах для разных лабораторий и подписок в файле. Передайте файл в сценарий вместо передачи отдельных параметров.

  • В этом примере для запуска скрипта PowerShell используется служба автоматизации Azure, но можно также использовать другие параметры, например конвейер сборки или выпуска.

Дальнейшие действия