Использование тегов с автоматизацией модулей Runbook Azure для контроля затрат

Недавно я написал здесь, в TechGenix, статью о том, как запускать/останавливать виртуальные машины в автоматизации Azure по расписанию, и жизнь удалась. На этой неделе я обратился к клиенту, которому нужно запускать и останавливать виртуальные машины, поэтому я подумал: «Отлично! Скопируйте и вставьте мою предыдущую статью, и Боб станет вашим дядей! Что ж, условия более сложные, чем моя первоначальная попытка. Цель этой статьи — показать, как удовлетворить более сложные требования и применить их к вашей среде Azure с помощью тегов.
Вот краткое изложение их требований. По сути, у них есть серверов, которые должны подчиняться следующим правилам:
- Они объединены в одну группу ресурсов.
- Они представляют собой значительное количество серверов (20+), которые требуют определенного порядка включения и выключения.
- У них есть два тега для управления группой ресурсов, а именно: PowerOnDays (число для каждого дня недели, где воскресенье равно 1) и PowerOnHours, который представляет собой диапазон с использованием 24-часового формата.
- Команде разработчиков может потребоваться протестировать некоторые новые функции. Они хотят изменить тег, чтобы запустить всю среду за пару часов, а не оставлять это операциям.
Основываясь на требованиях, мы собираемся создать runbook автоматизации. Этот модуль Runbook будет запускаться каждый час и в зависимости от условий начнет выполнять действия на виртуальных машинах.
Создание согласованного массива серверов
Первой задачей в нашем скрипте было прояснить логику создания списка серверов. Клиент бросил мне вызов, когда сказал, что у них есть несколько сред и «иногда» имена серверов могут иметь небольшие изменения между средами. Сценарий должен быть динамическим и использовать набор правил вместо статических имен.
После некоторого обсуждения с заказчиком я составил следующий список серверов и порядок их запуска или отключения. Я выделил уникальную строку каждого сервера, поэтому любые изменения префикса (который в примере включает PROD) и количества серверов не должны влиять на текущий процесс автоматизации.
Чтобы выполнить текущее требование, мы создали функционал с именем AddVMArray(), и я добавил Startup Order выше в переменную $vTiers. Скрипт ищет сервер со строкой FS0 и если находит, то добавляет в массив, а если серверов больше одного (например AzProdFS01 и AZProdFS02), то они оба будут добавлены в массив.
Функция AddVMArray ($rg){ $vTiers = '*FS0*','*APP0*','*FE0*','*Sec0*','*RDS0*' $fArray = @() For ($i= 0; $i -le (($vTiers).Count - 1); $i++){ #Debug: Write-Output $vtiers[$i] $tVM = Get-AzVM -Name $vTiers[$i] -ResourceGroupName $ rg If ((($tVM).Count) -eq 0) { $fArray += 'none' }else{ $tVM | ForEach{$fArray += $tVM.Name} } } вернуть $fArray }
Включение и выключение серверов
На этом этапе у нас есть согласованный список серверов, которые соответствуют серверам в любой заданной . Мы знаем, что от 1 до 5 у нас есть список для правильного запуска серверов, а от 5 до 1 у нас есть список для остановки серверов.
Была создана функция с именем VMGroup, функция получает два параметра: действие (вкл или выкл) и группу ресурсов.
Функция будет проходить на каждом сервере нашего массива и либо запускать, либо останавливать данную виртуальную машину и добавлять задержку, определенную в переменной, между операциями. Эта функция будет проверять текущее состояние сервера перед выдачей команды на запуск и остановку, таким образом мы экономим время.
Function VMGroup ($action, $ResourceGroup){ Write-Output "VMGroup Funtion --> " $ResourceGroup Write-Output "VMGroup Funtion --> " $action If (($action -eq $null) -or ($ResourceGroup - eq $null)) { Write-Output "Параметр Null в функции VMGroup"; break} $vArray = @() $vArray = AddVMArray($ResourceGroup) $vNumberofServers= ($varray).count - 1 If ($action -eq "On") { for ($i=0; $i -le $ vNumberofServers; $i++){ if ((get-azvm -Name $varray[$i]) -eq $null) { Write-Output "-> Status: VM " $varray[$i] " не существует" } Else { If ((Get-AZVM -Name $varray[$i] -status).PowerState -ne "ВМ работает") { Start-AZVM -Name $varray[$i] -ResourceGroupName $ResourceGroup Write-Output "-> Status: ВМ "$varray[$i]" запускается. Start-Sleep -Seconds $StartupDelay } Else { Write-Output "-> Status: VM " $varray[$i] " уже запущен." } } } } If ($action -eq "Off") { for ($i=$vNumberofServers; $i -ge 0; $i=$i-1){ if ((get-azvm -Name $varray[$ i]) -eq $null) { Write-Output "-> Status: VM " $varray[$i] " не существует" } Else { If ((Get-AZVM -Name $varray[$i] -status).PowerState -ne "ВМ освобождена") { Stop-AZVM -Name $varray[$i] -ResourceGroupName $ResourceGroup -Force Write-Output "-> Статус: ВМ "$varray[$i]" освобождается." Start-Sleep -Seconds $ShutdownDelay } Else { Write-Output "-> Status: VM " $varray[$i] " уже освобожден." } } } } }
Собираем все части вместе
Используя , которые мы создали ранее, у нас есть достаточно инструментов для создания списка серверов и выполнения на них операций запуска/остановки.
Прелесть использования функций в том, что все эти инструкции представляют собой повторно используемый код и могут адаптироваться на основе предоставленной информации.
Сам скрипт небольшой, и есть простой блок, в котором мы определяем некоторые начальные переменные.
$ShutdownDelay = 120 $StartupDelay = 300 $vCurrentDayofWeek = Get-Date -UFormat %u $vCurrentHour = (Get-Date).Hour – 4
Следующим шагом будет максимальное сужение. Мы будем использовать where-object для сбора только тех групп ресурсов, которые имеют определенное имя, и мы ищем два конкретных тега. Теги будут и , первый не должен быть пустым, а второй должен соответствовать сегодняшнему дню.
$gResourceGroups = Get-AzResourceGroup | где-объект {($_.ResourceGroupName -like '*grpServer*') -and ($_.Tags.PowerOnHours -ne $Null) -and ($_.Tags.PowerOnDaysOfWeek -like ("*" + $vCurrentDayofWeek + "*") }
Теперь, когда у нас есть список всех групп ресурсов, с которыми мы можем предпринять какие-либо действия, мы проведем серию тестов. Первый — получить тег PowerOnHours и сравнить его с текущим часом. Если текущий час принадлежит интервалу, скрипт включит виртуальные машины, если нет, то виртуальные машины будут выключены.
$gResourceGroups | % { Write-Output "==Working on " $_.ResourceGroupName" =====" Write-Output "Рабочие дни......:" $_.Tags.PowerOnDaysOfWeek Write-Output "Часы дня"..:" $_.Tags.PowerOnHours $vHourTemp = $_.Tags.PowerOnHours.Split("-") $vHourStart = $vHourTemp[0] $vHourEnd = $vHourTemp[1] Если (($_.Tags. PowerOnDaysOfWeek - как $vCurrentDayofWeek) -и (($vCurrentHour -ge $vHourStart) -and ($vCurrentHour -le $vHourEnd))){ $vAction = "On" }Else{ $vAction = "Off" } Write-Output $ vAction Write-Output $_.ResourceGroupName Write-Output $vEnv Write-Output "Действие: " $vaction Write-Output "rg....: " $_.ResourceGroupName VMGroup $vAction $_.ResourceGroupName }
Завершение
В этой статье мы рассмотрели сценарий, предназначенный для запуска и остановки виртуальных машин на основе тегов, связанных на уровне группы ресурсов. Сценарий является динамическим и использует список уникальных строк для создания списка серверов.
Весь код модуля Runbook можно найти на GitHub здесь.