Змяняны і выдаляны Azure VMs, выкарыстоўваючы PowerShell

З дапамогай PowerShell інжынеры і IT-адміністратары паспяхова аўтаматызуюць розныя задачы пры працы не толькі з on-premises, але і з хмарнымі інфраструктурамі, у прыватнасці, з Azure. Працаваць праз PowerShell у шэрагу выпадкаў значна зручней і хутчэй, чым праз Azure portal. Дзякуючы крос-платформавасці PowerShell можна выкарыстоўваць для любых АС.

Усё роўна, ці працуеце вы з Ubuntu, Red Hat або Windows - PowerShell дапаможа кантраляваць хмарныя рэсурсы. Выкарыстоўваючы модуль Azure PowerShell, да прыкладу, можна задаваць любыя ўласцівасці віртуальных машын.

У гэтым артыкуле мы разгледзім, як можна выкарыстоўваць PowerShell, каб змяніць памер ВМ у воблаку Azure, а таксама каб выдаліць ВМ і асацыіраваныя з ёй аб'екты.

Змяняны і выдаляны Azure VMs, выкарыстоўваючы PowerShell

Важна! Не забудзьцеся працерці рукі санітайзерам падрыхтавацца да працы:

  • Вам спатрэбіцца модуль Azure PowerShell Module - яго можна загрузіць з PowerShell Gallery камандай Install-Module Az.
  • Трэба аўтэнтыфікавацца ў воблаку Azure, дзе круціцца віртуальная машына, выканаўшы каманду Connect-AzAccount.

Для пачатку створым скрыпт, які рэсайзіт Azure VM. Адкрыем VS Code і захаваем новы PowerShell скрыпт пад назовам Resize-AzVirtualMachine.ps1 - У яго мы па ходзе прыкладу будзем дадаваць кавалкі кода.

Запытваем наяўныя памеры ВМ

Да таго, як памяняць памер ВМ, трэба пазнаць, якія наогул маюцца дапушчальныя памеры для віртуальных машын у воблаку Azure. Для гэтага трэба выканаць каманду Get-AzVMSize.

Такім чынам, для віртуальнай машыны devvm01 з рэсурснай групы DEV запытваем разнастайныя дапушчальныя памеры:

Get-AzVMSize -ResourceGroupName dev -VMName devvm01

(У рэальных задачах, натуральна, замест ResourceGroupName=dev и VMName=devvm01 вы будзеце ўказваць свае значэнні гэтых параметраў.)

Каманда верне прыкладна такі пералік:

Змяняны і выдаляны Azure VMs, выкарыстоўваючы PowerShell

Гэта ўсё магчымыя варыянты памераў, якія можна задаць для дадзенай віртуальнай машыны.

Рэсайзім машыну

Для прыкладу мы зробім рэсайз на новы памер Standard_B1ls - Ён на першым месцы ў спісе вышэй. (У рэальных задачах, зразумела, вы выбіраеце любы патрэбны вам памер.)

  1. Спачатку з дапамогай каманды Get-AzVM атрымліваем звесткі аб нашым аб'екце (віртуальнай машыне), захоўваючы іх у зменную $virtualMachine:
    $virtualMachine = Get-AzVM -ResourceGroupName dev -VMName devvm01
  2. Затым у гэтага аб'екта бярэм уласцівасць .HardwareProfile.VmSize і ўсталёўваны патрэбнае новае значэнне:
    $virtualMachine.HardwareProfile.VmSize = "Standard_B1ls"
  3. І зараз проста выконваем каманду абнаўлення ВМ - Update-AzVm:
    Update-AzVM -VM devvm01 -ResourceGroupName dev
  4. Пераконваемся, што ўсё прайшло паспяхова - для гэтага зноў жа запытваем інфармацыю аб нашым аб'екце і глядзім на ўласцівасць $virtualMachine.HardwareProfile:
    $virtualMachine = Get-AzVM -ResourceGroupName dev -VMName devvm01
    $virtualMachine.HardwareProfile

Калі там бачым Standard_B1ls - значыць, усё ў парадку, памер машыны зменены. Можна пайсці далей і развіць поспех - зарэсайзіць адразу некалькі ВМ, выкарыстоўваючы масіў.

А што наконт выдалення ВМ у Azure?

З выдаленнем не ўсё так проста і прамалінейна, як можа здацца. Бо трэба выдаліць яшчэ шэраг рэсурсаў, асацыіраваных з гэтай машынай, у тым ліку:

  • Старадж-кантэйнеры для дыягностыкі загрузкі (Boot diagnostics storage containers)
  • сеткавыя інтэрфейсы
  • Публічныя IP адрасы
  • Сістэмны дыск і blob, дзе захоўваецца яго статус
  • Дыскі з дадзенымі (data disks)

Таму мы створым функцыю і назавем яе Remove-AzrVirtualMachine - і яна будзе выдаляць не толькі Azure VM, але і ўсё вышэйпералічанае.

Ідзем стандартным шляхам і спачатку атрымліваем наш аб'ект (ВМ) з дапамогай каманды Get-AzVm. Для прыкладу няхай гэта будзе машына WINSRV19 з рэсурснай групы MyTestVMs.

Захаваем гэты аб'ект разам з усімі яго ўласцівасцямі ў зменную $vm:

$vm = Get-AzVm -Name WINSRV19 -ResourceGroupName MyTestVMs

Выдаляем кантэйнер з файламі дыягностыкі загрузкі

Пры стварэнні ВМ у Azure карыстачу прапануецца таксама стварыць і кантэйнер для захоўвання дыягностыкі загрузкі (boot diagnostics container), каб пры непаладках з загрузкай было да чаго звярнуцца на прадмет траблшутинга. Аднак пры выдаленні ВМ гэты кантэйнер застаецца працягваць сваё зараз бязмэтнае існаванне. Выправім гэтую сітуацыю.

  1. Перш высветлім, якому сторадж-акаўнту належыць гэты кантэйнер - для гэтага нам трэба адшукаць уласцівасць storageUri у нетрах аб'екта DiagnosticsProfile нашай ВМ. Для гэтага я выкарыстоўваю вось такі рэгулярны выраз:
    $diagSa = [regex]::match($vm.DiagnosticsProfile.bootDiagnostics.storageUri, '^http[s]?://(.+?)\.').groups[1].value
  2. Зараз трэба пазнаць імя кантэйнера, а для гэтага трэба атрымаць VM ID з дапамогай каманды Get-AzResource:
    
    if ($vm.Name.Length -gt 9) {
        $i = 9
    } else {
        $i = $vm.Name.Length - 1
    }
     
    $azResourceParams = @{
        'ResourceName' = WINSRV
        'ResourceType' = 'Microsoft.Compute/virtualMachines'
        'ResourceGroupName' = MyTestVMs
    }
     
    $vmResource = Get-AzResource @azResourceParams
    $vmId = $vmResource.Properties.VmId
    $diagContainerName = ('bootdiagnostics-{0}-{1}' -f $vm.Name.ToLower().Substring(0, $i), $vmId)
    
  3. Далей атрымліваем імя рэсурснай групы, да якой прыналежыць кантэйнер:
    $diagSaRg = (Get-AzStorageAccount | where { $_.StorageAccountName -eq $diagSa }).ResourceGroupName
  4. І зараз у нас ёсць усё неабходнае, каб выдаліць кантэйнер камандай Remove-AzStorageContainer:
    $saParams = @{
        'ResourceGroupName' = $diagSaRg
        'Name' = $diagSa
    }
     
    Get-AzStorageAccount @saParams | Get-AzStorageContainer | where { $_.Name-eq $diagContainerName } | Remove-AzStorageContainer -Force

Выдаляем ВМ

Зараз выдалім уласна віртуальную машыну, балазе мы ўжо стварылі зменную $vm для адпаведнага аб'екта. Што ж, запусцім каманду Remove-AzVm:

$null = $vm | Remove-AzVM -Force

Выдаляем сеткавы інтэрфейс і публічны IP-адрас

У нашай ВМ засталіся адзін (ці нават некалькі) сеткавых інтэрфейсаў (NICs) – каб выдаліць іх за непатрэбнасцю, пройдземся па ўласцівасці NetworkInterfaces нашага аб'екта VM і выдалім NIC камандай Remove-AzNetworkInterface. На выпадак, калі сеткавых інтэрфейсаў больш за адзін, выкарыстоўваем цыкл. Заадно для кожнага NIC праверым уласцівасць IpConfiguration на прадмет таго, ці ёсць у інтэрфейсу публічны IP адрас. Будзе такі выявіцца, выдалім яго камандай Remove-AzPublicIpAddress.

Вось прыклад як раз такога кода, дзе мы ў цыкле праглядаем усе NICs, выдаляем іх, правяраем, ці маецца публічны IP. Калі ёсць, то парсім уласцівасць PublicIpAddress, дастаем па ID імя адпаведнага рэсурсу і выдаляем яго:


foreach($nicUri in $vm.NetworkProfile.NetworkInterfaces.Id) {
    $nic = Get-AzNetworkInterface -ResourceGroupName $vm.ResourceGroupName -Name $nicUri.Split('/')[-1]
    Remove-AzNetworkInterface -Name $nic.Name -ResourceGroupName $vm.ResourceGroupName -Force

    foreach($ipConfig in $nic.IpConfigurations) {
        if($ipConfig.PublicIpAddress -ne $null) {
            Remove-AzPublicIpAddress -ResourceGroupName $vm.ResourceGroupName -Name $ipConfig.PublicIpAddress.Id.Split('/')[-1] -Force
        }
    }
}

Выдаляем сістэмны дыск

Дыск АС уяўляе сабой blob, для выдалення якога маецца каманда Remove-AzStorageBlob - але перад тым, як яе выконваць, трэба будзе задаць патрабаваныя значэнні яе параметрам. Для гэтага, у прыватнасці, трэба атрымаць імя стородж-кантэйнера, які змяшчае сістэмны дыск, і потым ужо перадаць яго дадзенай камандзе разам з адпаведным стородж-акаўнтам.

$osDiskUri = $vm.StorageProfile.OSDisk.Vhd.Uri
$osDiskContainerName = $osDiskUri.Split('/')[-2]
$osDiskStorageAcct = Get-AzStorageAccount | where { $_.StorageAccountName -eq $osDiskUri.Split('/')[2].Split('.')[0] }
$osDiskStorageAcct | Remove-AzStorageBlob -Container $osDiskContainerName -Blob $osDiskUri.Split('/')[-1]

Выдаляем Blob статусу сістэмнага дыска

Для гэтага, як вы ўжо напэўна здагадаліся, мы бярэм стородж-кантэйнер, у якім захоўваецца дадзеная кружэлка, і, маючы на ​​ўвазе, што blob у канцы ўтрымоўвае status, перадаем адпаведныя параметры камандзе выдалення Remove-AzStorageBlob:

$osDiskStorageAcct | Get-AzStorageBlob -Container $osDiskContainerName -Blob "$($vm.Name)*.status" | Remove-AzStorageBlob

І, нарэшце, выдаляем дыскі з дадзенымі

У нашай ВМ маглі заставацца дыскі з дадзенымі, якія былі да яе прыточаныя. Калі ў іх няма неабходнасці, выдалім і іх таксама. Спачатку распарсім StorageProfile нашай ВМ і знойдзем уласцівасць Uri. Калі дыскаў некалькі, які арганізуецца цыкл па URI. Для кожнага URI знойдзем адпаведны сторадж-акаўнт з дапамогай Get-AzStorageAccount. Затым распарсім storage URI, каб выцягнуць патрэбнае імя blob-a і перадаць яго камандзе выдалення Remove-AzStorageBlob разам са старадж-акаўнтам. Вось як гэта будзе выглядаць у кодзе:

if ($vm.DataDiskNames.Count -gt 0) {
    foreach ($uri in $vm.StorageProfile.DataDisks.Vhd.Uri) {
        $dataDiskStorageAcct = Get-AzStorageAccount -Name $uri.Split('/')[2].Split('.')[0]
        $dataDiskStorageAcct | Remove-AzStorageBlob -Container $uri.Split('/')[-2] -Blob $uri.Split('/')[-1]
    }
}

І вось "мы дабраліся да шчаслівага канца!" Цяпер з усіх гэтых фрагментаў трэба сабраць адзінае цэлае. Добры аўтар Адам Бертрам пайшоў насустрач карыстальнікам і зрабіў гэта сам. Вось спасылачка на выніковы скрыпт пад назвай Remove-AzrVirtualMachine.ps1:

GitHub

Спадзяюся, што гэтыя практычныя парады спатрэбяцца вам, каб зэканоміць сілы, час і сродкі пры працы з Azure VMs.

Крыніца: habr.com

Дадаць каментар