Неважно, работаете ли вы с Ubuntu, Red Hat или Windows PowerShell поможет контролировать облачные ресурсы. Используя модуль Azure PowerShell, к примеру, можно задавать любые свойства виртуальных машин.
В этой статье мы рассмотрим, как можно использовать PowerShell, чтобы изменить размер ВМ в облаке Azure, а также чтобы удалить ВМ и ассоциированные с ней объекты.
Важно! Не забудьте
- Вам понадобится модуль 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 вы будете указывать свои значения этих параметров.)
Команда вернет примерно такой перечень:
Это все возможные варианты размеров, которые можно задать для данной виртуальной машины.
Ресайзим машину
Для примера мы сделаем ресайз на новый размер Standard_B1ls он на первом месте в списке выше. (В реальных задачах, разумеется, вы выбираете любой нужный вам размер.)
- Сначала с помощью команды
Get-AzVM
получаем сведения о нашем объекте (виртуальной машине), сохраняя их в переменную$virtualMachine
:$virtualMachine = Get-AzVM -ResourceGroupName dev -VMName devvm01
- Затем у этого объекта берем свойство
.HardwareProfile.VmSize
и устанавливаем нужное новое значение:$virtualMachine.HardwareProfile.VmSize = "Standard_B1ls"
- И теперь просто выполняем команду обновления ВМ
Update-AzVm
:Update-AzVM -VM devvm01 -ResourceGroupName dev
- Убеждаемся, что всё прошло успешно для этого опять же
запрашиваем информацию о нашем объекте и смотрим на свойство
$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), чтобы при неполадках с загрузкой было к чему обратиться на предмет траблшутинга. Однако при удалении ВМ этот контейнер остается продолжать свое теперь бесцельное существование. Исправим эту ситуацию.
- Сперва выясним, какому сторадж-аккаунту принадлежит этот
контейнер для этого нам нужно разыскать свойство
storageUri
в недрах объектаDiagnosticsProfile
нашей ВМ. Для этого я использую вот такое регулярное выражение:$diagSa = [regex]::match($vm.DiagnosticsProfile.bootDiagnostics.storageUri, '^http[s]?://(.+?)\\.').groups[1].value
- Теперь надо узнать имя контейнера, а для этого нужно получить
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)
- Далее получаем имя ресурсной группы, к которой принадлежит
контейнер:
$diagSaRg = (Get-AzStorageAccount | where { $_.StorageAccountName -eq $diagSa }).ResourceGroupName
- И теперь у нас есть все необходимое, чтобы удалить контейнер
командой
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.