Introducción:
En entornos de nube como Azure, es fundamental optimizar el uso de recursos para reducir costos y mejorar la eficiencia operativa. Una de las prácticas recomendadas es apagar las máquinas virtuales (VMs) cuando no están en uso y encenderlas solo cuando sea necesario. En este blog, exploraremos cómo automatizar este proceso utilizando Tags en Azure y un script de PowerShell ejecutado desde un Automation Account.
Configuración Inicial:
Antes de sumergirnos en el script, asegúrate de tener un Automation Account configurado en Azure con las credenciales necesarias. El script utiliza un servicio principal para la autenticación.
Automation Accounts
Nos vamos al servicio Automation Accounts (En caso que no exista lo creamos)
El Script:
El script PowerShell proporcionado se encarga de apagar y encender VMs en función de la programación definida en sus Tags. Se inicia sesión en Azure utilizando las credenciales del Automation Account y luego examina las VMs en función de la programación diaria y de fin de semana.
$connectionName = "AzureRunAsConnection"
try
{
# Get the connection "AzureRunAsConnection "
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName
"Logging in to Azure..."
Connect-AzAccount `
-ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = "Connection $connectionName not found."
throw $ErrorMessage
} else{
Write-Error -Message $_.Exception
throw $_.Exception
}
}
$Today = Get-Date -Format dd/MM/yyyy
$day = (Get-Date).DayOfWeek
$days = (Get-AzAutomationVariable -ResourceGroupName "Mapal_Infra" -AutomationAccount "mapalinforchestrator" -Name "DaysOfWeek").Value -split ","
$Weekend = (Get-AzAutomationVariable -ResourceGroupName "Mapal_Infra" -AutomationAccount "mapalinforchestrator" -Name "DaysOfWeekend").Value -split ","
#Schedule horario invierno
$Schedule = (Get-AzAutomationJob -ResourceGroupName Mapal_infra -AutomationAccountName mapalinforchestrator | Select-Object * -First 1).CreationTime.AddHours(1).ToString('HH:mm')
#Schedule horario verano
#$Schedule = (Get-AzAutomationJob -ResourceGroupName Mapal_infra -AutomationAccountName mapalinforchestrator | Select-Object * -First 1).CreationTime.AddHours(2).ToString('HH:mm')
Write-Output "Tarea iniciada a las $Schedule"
if ($days -contains $day) {
$Vms = Get-AzVM | Where-Object {$_.Tags.PowerOff -eq "$Schedule"}
foreach ($Vm in $Vms) {
$Status = (Get-AzVM -Name $Vm.Name -Status).PowerState
if ($Status -eq "VM running" -or "VM stopped") {
$Name = $Vm.Name
Stop-AzVM -Name $Vm.Name -ResourceGroupName $Vm.ResourceGroupName -Force
Write-Output "Apagando servidores..."
Write-Output "Servidor $Name apagado"
}
}
$Vms = Get-AzVM | Where-Object {$_.Tags.PowerOn -eq "$Schedule"}
foreach ($Vm in $Vms) {
$Status = (Get-AzVM -Name $Vm.Name -Status).PowerState
if ($Status -eq "VM deallocated") {
Start-AzVM -Name $Vm.Name -ResourceGroupName $Vm.ResourceGroupName
$Name = $Vm.Name
Write-Output "Encendiendo servidores..."
Write-Output "Servidor $Name encendido"
}
}
}
if ($Weekend -contains $day) {
$Vms = Get-AzVM | Where-Object {($_.Tags.WeekendPowerOn -eq "Yes") -and ($_.Tags.PowerOff -eq "$Schedule")}
foreach ($Vm in $Vms) {
$Status = (Get-AzVM -Name $Vm.Name -Status).PowerState
if ($Status -eq "VM running" -or "VM stopped") {
$Name = $Vm.Name
Stop-AzVM -Name $Vm.Name -ResourceGroupName $Vm.ResourceGroupName -Force
Write-Output "Apagando servidores..."
Write-Output "Servidor $Name apagado"
}
}
$Vms = Get-AzVM | Where-Object {($_.Tags.WeekendPowerOn -eq "Yes") -and ($_.Tags.PowerOn -eq "$Schedule")}
foreach ($Vm in $Vms) {
$Status = (Get-AzVM -Name $Vm.Name -Status).PowerState
if ($Status -eq "VM deallocated") {
Start-AzVM -Name $Vm.Name -ResourceGroupName $Vm.ResourceGroupName
$Name = $Vm.Name
Write-Output "Encendiendo servidores..."
Write-Output "Servidor $Name encendido"
}
}
}
else {
Write-Output "No hay servidores con esta programación."
}
Creamos el certificado
Creamos las conexión
En Schedules creamos cuando queremos que se ejecute el runbook
Programación Diaria:
Las VMs se apagan y encienden según la programación diaria establecida en los Tags «PowerOff» y «PowerOn». El script verifica si el día actual corresponde a los días programados y realiza las operaciones correspondientes.
Programación de Fin de Semana:
Adicionalmente, el script también maneja la programación de fin de semana, donde las VMs pueden tener configuraciones especiales. En este caso, se verifica si el día actual es un día de fin de semana y si la VM está marcada para encenderse o apagarse en ese horario específico.
@rokitoh me puedes guiar en como crear el certificado? Compartes los TAGS a definirle a cada VM