Definir a ordem de arranque das VMs do DevTest Lab com Automatização do Azure
Este artigo explica como iniciar máquinas virtuais (VMs) do DevTest Labs por uma ordem específica com um runbook do PowerShell no Automatização do Azure. O script do PowerShell utiliza etiquetas em VMs de laboratório, para que possa alterar a ordem de arranque sem ter de alterar o script.
A funcionalidade de início automático do DevTest Labs pode configurar VMs de laboratório para iniciar automaticamente num determinado momento. No entanto, por vezes, poderá querer que as VMs de laboratório comecem numa sequência específica. Por exemplo, se uma VM de jumpbox num laboratório for o ponto de acesso para as outras VMs, a VM jumpbox tem de ser iniciada antes das outras VMs.
Pré-requisitos
Crie e aplique uma etiqueta denominadaStartupOrder a todas as VMs de laboratório com um valor de arranque adequado, de 0 a 10. Designe as máquinas que não precisam de ser iniciadas como -1.
Crie uma conta Automatização do Azure ao seguir as instruções em Criar uma conta Automatização do Azure autónoma. Selecione a opção Contas Run As quando criar a conta.
Criar o runbook do PowerShell
- Na página Descrição geral da Conta de Automatização, selecione Runbooks no menu esquerdo.
- Na página Runbooks , selecione Criar um runbook.
- Siga as instruções em Criar um runbook do PowerShell de Automatização com a identidade gerida para criar um runbook do PowerShell. Preencha o runbook com o seguinte script do PowerShell.
Preparar o script do PowerShell
O script seguinte utiliza o nome da subscrição e o nome do laboratório como parâmetros. O script obtém todas as VMs no laboratório e analisa as respetivas informações de etiqueta para criar uma lista de nomes de VMs e o respetivo pedido de arranque. O script percorre a lista por ordem e inicia as VMs.
Se existirem várias VMs num número de encomenda específico, essas VMs começam de forma assíncrona com tarefas do PowerShell. As VMs que não têm uma etiqueta têm o valor de arranque definido como 10 e começam em último por predefinição. O script ignora quaisquer VMs que tenham valores de etiqueta que não 0 a 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"
}
}
Executar o script
Para executar este script diariamente, crie uma agenda na Conta de Automatização e ligue a agenda ao runbook.
Num cenário empresarial que tenha várias subscrições com vários laboratórios, pode armazenar as informações de parâmetros para laboratórios e subscrições diferentes num ficheiro. Transmita o ficheiro para o script em vez de transmitir os parâmetros individuais.
Este exemplo utiliza Automatização do Azure para executar o script do PowerShell, mas também pode utilizar outras opções, como um pipeline de compilação/versão.