Definición del orden de inicio de máquinas virtuales de DevTest Labs con Azure Automation
En este artículo se detalla cómo iniciar máquinas virtuales (VM) de DevTest Labs en un orden específico mediante el uso de un runbook de PowerShell en Azure Automation. El script de PowerShell utiliza etiquetas en las máquinas virtuales del laboratorio para permitirle controlar el orden de inicio sin tener que cambiar el script.
La característica de inicio automático de DevTest Labs le permite configurar el inicio automático de las máquinas virtuales a una hora determinada. Sin embargo, a veces es posible que quiera que las máquinas virtuales del laboratorio se inicien en una secuencia específica. Por ejemplo, si la máquina virtual jumpbox de un laboratorio es el punto de acceso a las otras máquinas virtuales, esta deberá iniciarse antes que las demás.
Requisitos previos
Cree y aplique una etiqueta denominada StartupOrder a todas las máquinas virtuales del laboratorio que contenga el valor de inicio adecuado de 0 a 10. Designe cualquier máquina que no deba iniciarse con el valor -1.
Cree una cuenta de Azure Automation siguiendo las instrucciones del artículo Creación de una cuenta independiente de Azure Automation. Al crear la cuenta, elija la opción Cuentas de ejecución.
Creación del runbook de PowerShell
- En la página Información general de la cuenta de Automation, seleccione Runbooks en el menú izquierdo.
- En la página Runbooks seleccione Crear un Runbook.
- Siga las instrucciones que se detallan en el artículo Tutorial: Creación de un runbook de PowerShell de Automation mediante una identidad administrada para crear un runbook de PowerShell. Rellene el runbook con el siguiente script de PowerShell.
Preparación del script de PowerShell
El siguiente script utiliza los nombres de la suscripción y el laboratorio como parámetros. El script detectará todas las máquinas virtuales del laboratorio y analizará la información de sus etiquetas para crear una lista de los nombres de las máquinas y su orden de inicio. El script recorrerá e iniciará las máquinas virtuales en orden de lista.
Si varias máquinas virtuales comparten un número de orden específico, estas se iniciarán de forma asincrónica mediante trabajos de PowerShell. El valor de inicio de las máquinas virtuales que no tengan una etiqueta se establecerá en 10 y, de forma predeterminada, estas serán las últimas en iniciarse. El script omitirá las máquinas virtuales que tengan valores de etiqueta que no vayan del 0 al 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"
}
}
Ejecute el script.
Para ejecutar este script diariamente, cree una programación en la cuenta de Automation y vincúlela con el runbook.
En un escenario empresarial con varias suscripciones y laboratorios, podrá utilizar un archivo para almacenar la información de los parámetros de los diferentes laboratorios y suscripciones. Pase el archivo al script en lugar de pasar los parámetros individuales.
Aunque en este ejemplo se muestra cómo Azure Automation ejecuta el script de PowerShell, también puede usar otras opciones, como una canalización de versión o compilación.