Provisioning di una VM ARM via PowerShell

Questo post è stato scritto da Riccardo Cappello, Technical Manager Vivido.

Capita molto spesso di avere il bisogno di creare velocemente delle VM su Azure per effettuare dei test o comunque per necessità impellenti. Il Portale Azure è molto intuitivo e immediato nell’adempiere questa funzionalità, ma vediamo come creare un VM via PowerShell con la stessa rapidità.

Prima di tutto è necessario avere installato Azure Powershell, se non lo abbiamo già possiamo consultare questa ottima guida. La versione minima per eseguire questi script è la 1.0.0.

Se abbiamo già installato Azure Powershell, apriamolo e lanciamo questo semplice comando per conoscere la versione presente.

 Get-Module AzureRM | format-table version

1

Iniziamo quindi con il primo fondamentale passaggio: stabiliamo una connessione con Azure eseguendo

 Login-AzureRmAccount

Ci verrà mostrata la finestra di login dove è necessario inserire le nostre credenziali per accedere ad Azure. Il risultato sarà qualcosa di simile

2

Se il nostro account Azure ha associato più Sottoscrizioni è necessario impostare quella dove vogliamo creare la nostra VM.

Possiamo usare PowerShell per elencare le Sottoscrizioni e recuperarne id e nome con il comando

 Get-AzureRmSubscription | sort SubscriptionName | Select SubscriptionId, SubscriptionName

3

Copiamo il SubscriptionId della sottoscrizione da selezionare ed eseguiamo

 Select-AzureRmSubscription -SubscriptionId 'id sottoscrizione fra virgolette'

Oppure se preferiamo copiare il SubscriptionName eseguiamo

 Select-AzureRmSubscription -SubscriptionName 'nome sottoscrizione fra virgolette'

Ora creiamo alcune variabili che ci torneranno utili negli comandi successivi

 # Impostiamo il DataCenter dove vogliamo creare la mia VM.
 # Un elenco completo con il comando: Get-AzureLocation | sort Name | Select Name
 $location = 'West Europe'
 # Il nome dello storage account dove depositare la VM.
 # Può avere solo lettere minuscole e numeri e da 3 a 24 caratteri
 # e deve essere univoco in tutto Azure.
 # Per testare se il nome dello storage account è già presente,
 # usiamo il comando: Test-AzureName -Storage $storageAccount
 # Se il comando di test ritorna False, il nome dello storage non è usato e può essere scelto
 $storageAccount = 'vmstoragemydev01'
 # Il contenitore dello storage dove fisicamente saranno salvati i dati della VM
 $defaultContainer = 'vhds'
 # La dimensione dell'istanza della VM.
 # Un elenco completo con il comando Get-AzureLocation | Where {$_.Name -eq $location}
 # e vedendo le istanze disponibili presenti alla voce VirtualMachineRoleSizes
 # oppuere andando a questo link
 $instanceSize = 'Standard_D1_v2'
 # Il nome che desideriamo dare alla VM
 $vmName = 'my-dev01'
 # Il nome utente dell'account locale della VM
 $adminLogin = 'myadmin'
 # La password dell'utende dell'account locale della VM
 $adminPassword = 'MyP@ssw0rd$'
 # Il nome del Virtual Network dove si appoggerà la VM
 $vnetName = 'MyNetwork'
 # Il nome della subnet del Virtual Network
 $vnetSubnet = 'clients'
 # Il nome del Gruppo di Risorse / Resource Group
 $resourceGroupName = "MyVmClients"
 # Il nome del disco che conterrà il sistema operativo della VM
 $diskname = "MY_DEV01_OSDisk"
 # Il nome dell’etichetta del dominio che assumerà la VM dall'esterno
 $domainNameLabel = 'my-dev01'

Creiamo adesso il Resource Group

 New-AzureRmResourceGroup -Name $resourceGroupName -Location $location

4

E a ruota creiamo lo storage, in questo caso ridondato localmente (Standard_LRS).

 New-AzureRmStorageAccount -StorageAccountName $storageAccount -Location $location -Type Standard_LRS -ResourceGroupName $resourceGroupName

 5

Assicuriamoci ora di creare una Subnet e un Virtual Network.

 $subnet = New-AzureRmVirtualNetworkSubnetConfig -Name $vnetSubnet -AddressPrefix '192.168.1.0/24'
$vnet = New-AzureRmVirtualNetwork -Name $vnetName -ResourceGroupName $resourceGroupName -Location $location -AddressPrefix '192.168.1.0/24' -Subnet $subnet

Una volta create la vnet, riprendiamo il valori della subnet che in fase di creazione sono stati correlati con un ID che ci servirà più avanti.

 $subnet = Get-AzureRmVirtualNetworkSubnetConfig -VirtualNetwork $vnet -Name $vnetSubnet

Creiamo ora un Public IP Address (PIP) e una Network Interface (NIC).

 $pip = New-AzureRmPublicIpAddress -Name "${vmName}_ip" -ResourceGroupName $resourceGroupName -DomainNameLabel $domainNameLabel -Location $location -AllocationMethod Dynamic 
 $nic = New-AzureRmNetworkInterface -Name "${vmName}_nic1" -SubnetId $subnet.Id -Location $location -ResourceGroupName $resourceGroupName -PublicIpAddressId $pip.Id

Prepariamo poi le credenziali per l’utente amministratore della VM

 $vmCreds = New-Object System.Management.Automation.PSCredential($adminLogin, ($adminPassword | ConvertTo-SecureString -AsPlainText -Force))  

Scegliamo l’immagine della VM che vogliamo creare. Se la Subscription è collegata ai benefici MSDN, è possibile testare anche alcuni tipi di VM altrimenti non presenti, come immagini con Windows 10. Possiamo risalire prima all’elenco dei publisher con il comando

 Get-AzureRmVMImagePublisher -Location $location | Sort PublisherName | Select PublisherName 

Scegliamo per esempio “MicrosoftVisualStudio“, provider Microsoft per immagini di VM con installazioni di Visual Studio già comprese.
Vediamo quindi le offerte di questo provider.  

 Get-AzureRmVMImageOffer -Location $location -PublisherName "MicrosoftVisualStudio" | Sort Offer | Select Offer  

Anche qui scegliamo “VisualStudio” e vediamo gli Sku relativi.  

 Get-AzureRmVMImageSku -Location $location -PublisherName "MicrosoftVisualStudio" -Offer "VisualStudio" | Sort Skus | Select Skus  

Di tutta la lista, proviamo a scegliere “"VS-2015-Comm-VSU2-AzureSDK-29-WS2012R2“ ovvero un Windows Server 2012 R2 con Visual Studio 2015 Update 2 e Azure SDK 2.9.
Preleviamo quindi l’immagine stando attenti a selezionare l’ultima versione disponibile nel caso ne fossero pubblicate più di una.  

 $vmImage = Get-AzureRmVMImage -Location $location -PublisherName "MicrosoftVisualStudio" -Offer "VisualStudio" -Skus "VS-2015-Comm-VSU2-AzureSDK-29-WS2012R2" | Sort-Object -Descending -Property Version | Select-Object -First(1) 

E’ giunto adesso il momento di iniziare a comporre i pezzi e a completare la configurazione per la nostra VM.
Prepariamo prima la configurazione di base.

 $vmconfig = New-AzureRmVMConfig  -VMName $vmName -VMSize $instanceSize

Aggiungiamo poi le configurazioni per il Sistema Operativo, che sarà di tipo Windows.  

 Set-AzureRmVMOperatingSystem -Windows -VM $vmconfig -ProvisionVMAgent -EnableAutoUpdate -Credential $vmCreds -ComputerName $vmname

Inseriamo i riferimenti all’immagine della VM che abbiamo scelto in precedenza  

 Set-AzureRmVMSourceImage -VM $vmconfig -PublisherName $vmImage.PublisherName -Offer $vmImage.Offer -Skus $vmImage.Skus -Version $vmImage.Version

Ed il network precedentemente creato    

 Add-AzureRmVMNetworkInterface -VM $vmconfig -Id $nic.Id 

Dallo Storage calcoliamo il percorso che avrà il file VHD (Virtual Hard Disk) che conterrà il disco del Sistema Operativo e inseriamolo nella configurazione.

 $storacct = Get-AzureRmStorageAccount -ResourceGroupName $resourceGroupName -Name $storageAccount
$vhduri = $storacct.PrimaryEndpoints.Blob.OriginalString + "vhds/${diskname}.vhd"
Set-AzureRmVMOSDisk -VM $vmconfig -Name $diskname -VhdUri $vhduri -Caching ReadWrite -CreateOption fromImage 

Se proviamo a stampare la variabile $vmconfig vediamo che abbiamo costruito un file JSON con tutte le caratteristiche proprie della VM che andremo a creare.   6 7

Ed ecco il comando che effettuerà il provisioning della VM.

 New-AzureRMVM -ResourceGroupName $resourceGroupName -Location $location -VM $vmconfig

8Una volta terminato il Provisioning, possiamo vedere lo stato della VM eseguendo

 Get-AzureRmVm -Name $vmName -ResourceGroupName $resourceGroupName

9 10

Questa è una panaromica sul portale di quanto è stato creato da PowerShell

12

Se il Network fosse connesso tramite VPN S2S al network On-Premise o comunque se il Domain Controller fosse raggiungubile dalla VM, dopo la creazione potremo aggiungere un breve comando che effettua la Join a Dominio della VM.

 $DomainName = "DOMINIO.LAN"
$DomainJoinAdminName = "DOMINIO.LAN\utente"
$DomainJoinPassword = "Password"
 Set-AzureRMVMExtension 
   -VMName $VMName 
   –ResourceGroupName $ResourceGroupName
   -Name "JoinAD" 
   -ExtensionType "JsonADDomainExtension" 
   -Publisher "Microsoft.Compute" 
   -TypeHandlerVersion "1.0" 
   -Location $location 
   -Settings @{ "Name" = $DomainName; "OUPath" = ""; "User" = $DomainJoinAdminName; "Restart" = "true"; "Options" = 3} 
   -ProtectedSettings @{"Password" = $DomainJoinPassword}

Buon divertimento quindi con PowerShell e le VM ARM!