Nouvelles Chroniques d'Amethyste

Penser au Sens, pas au Verbe

Pilotez vos VM Azure avec Powershell

Poster un commentaire

En ce moment je travaille beaucoup sur les scripts de création et de contrôle de VM Azure depuis PowerShell. Je n’ai pas trouvé de tutoriel en français qui soit complet alors je me propose de l’écrire.

Pour alléger cet article assez long j’ai publié un article d’introduction ici:

https://amethyste16.wordpress.com/2015/04/09/petite-synthese-sur-les-vhd-image-disk-et-vm-sous-azure/

 

L’article est articulé autour des chapitres principaux suivant :

  • Charger un VHD dans Azure
  • Alimenter les magasins disque et image
  • Création de la VM
  • Scénarios avancés
  • Arrêter/lancer la VM
  • Supprimer les ressources VM
  • Point de terminaison, équilibrage de charge

Pour toute la suite on supposera définies dans les scripts les variables PowerShell suivantes :


$familyName="Windows Server 2012 R2 Datacenter"
$size="Small"
$vmName="AmethysteVM"
$serviceName="serviceAmethyste"
$location ="West Europe"
$user="admin489"
$pwd="azerty@12345"
# nom du storage par défaut
$storage ="demordpstorage"

# obtient le nom de l’image
$imageName = get-azurevmimage '
| where {$_.ImageFamily -eq $familyName} '
| sort PublishedDate -Descending|select -ExpandProperty ImageName -First 1

 

Notez que la valeur de $size est sensible à la casse.

Une autre variable récurrente sera:

$config : la configuration d’une VM

On verra au moment voulu comment elle est construite.

J’ai testé TOUS les scripts que je présente et vous encourage à faire de même. N’hésitez évidemment pas à en adapter les valeurs si nécessaire.

Je vais surtout m’intéresser aux VM Windows. Les VM Linux ne sont pas bien différentes à vrai dire. La différence porte surtout sur les accès distants et la façon dont on les généralise.

Charger un VHD dans Azure

Charger un VHD depuis un emplacement on premises est une façon de construire des images ou des disques personnalisés. On dispose de 4 options :

  1. Blob vers le magasin d’images
  2. Blob vers le magasin de disques
  3. On premises vers un blob
  4. VM Depot vers le magasin d’image

2015-04-13_22-06-33

Le portail ne permet pas de charger un VHD dans un blob, mais on peut le faire en PowerShell avec Add-AzureVHD :


$storage ="demordpstorage"
$diskName="data2"
$destination = "https://$storage.blob.core.windows.net/uploads/$diskName.vhd"
$source ="c:\XXX\data2.vhd"
Add-AzureVhd -Destination $destination -LocalFilePath $source

 

 

2015-04-06_00-29-28

L’opération est plus ou moins longue selon la taille du fichier. Une fois terminé on a le plaisir de retrouver notre fichier dans le conteneur :

2015-04-13_22-10-30

Add-AzureVHD convertit automatiquement un disque virtuel dynamique en disque virtuel fixe, seul format supporté actuellement. On peut remplacer un disque existant en précisant le paramètre OverWrite.

Note: on pourrait bien sûr le pousser dans le blob par d’autres moyens, mais Add-AzureVHD est spécifique au format VHD et procède à quelques optimisations.

 

Save-AzureVHD fait l’opération inverse:

Save-AzureVhd -Source $storagePath -LocalFilePath $sourcePath

Cette fois on peut aussi procéder depuis le portail en invoquant le menu DOWNLOAD.

 

Nous disposons maintenant d’un VHD. Nous verrons dans les chapitres qui suivent comment transformer un VHD en disque ou en image.

Depuis le portail on se rend dans l’onglet Virtual Machines et selon ce que l’on souhaite faire on sélectionne l’onglet IMAGES ou DISKS :

2015-04-13_22-12-53

On utilise alors les menus de création proposés.

Si on charge une image :

2015-04-13_22-13-50

On remarque la présence du menu BROWSE VM DEPOT qui permet d’obtenir une image depuis la galerie VM Depot.

Dans tous les cas le menu CREATE fonctionne de la même façon et demande de choisir un VHD situé dans un blob :

2015-04-13_22-15-04

Alimenter le magasin des images

Il est possible de créer une image de 2 façons :

  1. En capturant une VM avec Save-AzureVMImage
  2. Depuis un VHD avec Add-AzureVMImage

Les images seront créées dans le magasin des images de votre abonnement.

 

PowerShell ne permet pas de généraliser une VM, mais on peut ensuite en lancer la capture avec Save-AzureVMImage:

Save-AzureVMImage -ServiceName $serviceName -Name $vmName -ImageName “customName” -OSState Generalized

L’image capturée apparaît dans le magasin des images:

2015-04-13_22-17-18

Le paramètre OSState attend une des valeurs suivantes :

  • Generalized Pour créer une image généralisée
  • Specialized Pour créer une image spécialisée.
    Une image spécialisée fonctionne un peu comme un instantané d’une VM. On va s’en servir pour sauvegarder une VM dans un certain état afin de pouvoir la restaurer si la suite se passe mal

 

En l’absence de OSState, on créée une image héritée. Une image héritée n’est qu’un disque OS. Les disques de données éventuels seront perdus.

 

Si on dispose dans un blob d’une image généralisée, alors on peut la charger dans le magasin des images avec Add-AzureVMImage :

Add-AzureVMImage -MediaLocation $destination -ImageName « customImage » -OS Windows

MediaLocation est l’url du vhd dans le blob. D’autres paramètres existent, mais ce sont les paramètres obligatoires.

2015-04-13_22-20-15

Alimenter le magasin des disques

La commande est Add-AzureDisk qui permet d’ajouter un disque bootable ou bien un disque de données.

Add-AzureDisk -MediaLocation $destination -DiskName « customDisk »

Ajoute un disque de données sous le nom customDisk.

Pour ajouter un disque OS on ajoute :

-OS « Windows »

Création d’une VM

Commandes de base

On créée une VM avec l’une de ces méthodes:

  1. New-AzureVM
  2. New-AzureQuickVM

La première méthode est la plus complète, c’est essentiellement celle que l’on utilisera dans cet article. La deuxième est similaire à la commande du même nom du portail.

Nous avons vu dans l’article de présentation que les étapes de la création d’une VM sont les suivantes :

2015-04-13_22-24-34

On peut selon la situation partir d’un disque virtuel, d’une image ou d’un disque. Le cas de la VHD a été analysé dans le chapitre précédent.
On peut retrouver la liste de toutes les VM de l’abonnement en lançant:

Get-AzureVM

2015-04-03_12-34-03

Si on s’intéresse à une VM en particulier:

Get-AzureVM -ServiceName $serviceName -Name $vmName

Il est possible de simplifier un peu la syntaxe:

Get-AzureVM $serviceName $vmName

Il faudra alors mettre les paramètres dans l’ordre indiqué. Je suis un peu moins fan de cette écrire.

 

Lorsque l’on créée une VM on a le choix entre deux niveaux qui correspondent à des tarifications et des capacités:

  • Basic
  • Standard

En Basic on va jusqu’à A4 et le flux maxi est de 300 IOPS par disque contre 500 en Standard. Il y a aussi d’autres différences comme le l’équilibrage de charge :

https://msdn.microsoft.com/en-us/library/azure/dn197896.aspx

Comment sélectionne-t-on un modèle avec PowerShell ? On le fait en fournissant le nom de la VM. Par exemple avec les paramètres utilisés par défaut dans cet article on va créer des VM de taille « Small » ce qui correspond à une machine A1 de niveau standard.

Pour avoir la même machine en Basic on devrait utiliser « Basic_A1″.

Depuis une image

Le script de base est celui-ci:


New-AzureVMConfig -Name $vmName -InstanceSize $size -ImageName $imageName |
Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd |
New-AzureVM -ServiceName $serviceName  -Location $location

 

On commence par créer une configuration Azure avec New-AzureVmConfig. Cette configuration contient toutes les informations utiles pour qu’Azure puisse gérer et héberger la VM. Cette commande attend en particulier le nom de l’image qui servira à construire la VM.

Add-AzureProvisioningConfig est utilisé pour paramétrer l’état de la VM, par exemple le logon/mot de passe pour s’y connecter à distance, un certificat, modifier le fuseau horaire, bloquer la mise à jour automatique… Les informations de provisionnement sont les informations pour paramétrer la VM indépendamment d’Azure.

Nous avons passé le paramètre Windows qui indique que l’OS est Windows. Deux autres options sont également possibles:

  1. Linux
  2. Domain
    Rattacher la VM à un domaine AD

Un point d’attention à surveiller est le stockage par défaut. Pour en savoir plus on pourra lire ceci:

https://amethyste16.wordpress.com/2015/04/01/ma-vm-azure-contre-le-storage-fantome/

 

Enfin New-AzureVM construit la VM dont elle reçoit les deux configurations et l’installe dans le service cloud proposé. On peut créer jusqu’à 50 VM dans un service.

 

La création et le démarrage des VM peut être assez long, il peut être utile d’attendre que celles-ci aient démarrées, on ajoute pour cela un petit paramètre à New-AzureVM:

 New-AzureVM -ServiceName $serviceName  -Location $locationWaitForBoot

 

PowerShell permet de tunneler facilement les commandes. On peut préférer séparer les étapes et réorganiser le code comme celui-ci:


New-AzureService -ServiceName $serviceName -Location $location

$imageName = get-azurevmimage | where {$_.ImageFamily -eq $familyName}| sort PublishedDate -Descending|select -ExpandProperty ImageName -First 1

$config = new-azurevmconfig -Name $vmName -InstanceSize $size -ImageName $imageName
$config | Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd
$config | New-AzureVM -ServiceName $serviceName

 

New-AzureService permet de créer un cloud service vide. Il est peut être souhaitable de vérifier au préalable la disponibilité du domaine de service:

Test-AzureName -Service -Name $serviceName

Ce n’est pas très intuitif, mais le service est libre si la fonction retourne false. Le fait que true soit retourné ne signifie pas que l’on ne puisse pas s’en servir. Vous êtes peut-être propriétaire de ce domaine.

 

New-AzureVM gère deux scénarios:

  1. création d’une VM dans un nouveau service
  2. ajout d’une VM dans un service existant

Dans le premier cas on devra ajouter soit Location soit AffinityGroup. Dans le deuxième cas seul ServiceName est nécessaire. On peut laisser Location, mais cela provoque un warning.

Note: New-AzureQuickVM est plus rigide. Dans le deuxième scénario on ne doit pas ajouter Location sous peine de lever une exception

 

On peut facilement créer plusieurs VM en même temps à l’aide du petit script suivant:


New-AzureService -ServiceName $serviceName -Location $location
$configs = @()
for($i=1; $i -le 4; $i++)
{
$CurrentName = $vmName + $i
$Config = New-AzureVMConfig -Name $CurrentName -InstanceSize $size -ImageName $imageName
$Config | Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd
$Configs += $Config
}
New-AzureVM -ServiceName $serviceName -VMs $configs

 

Il construit 4 VM. La boucle for est chargée de créer une table de configuration pour chaque VM. Cette table est passée à New-AzureVM via son paramètre VMS et à la fin:

2015-04-08_23-20-32

Note: le paramètre est VMS, ne pas le confondre avec un autre paramètre qui s’appelle VM et est disponible dans certaines autres cmdlets. Je vous laisse deviner la différence…

Si on se rend dans le stockage on trouve bien sûr 4 blobs:

2015-04-08_23-51-20

La taille, 127 Go, est la taille max du disque OS. Les disques de données peuvent faire jusqu’à 1 To.

Depuis un disque

On peut soit attacher un disque à une VM s’il s’agit d’un disque de données, soit s’en servir pour créer une VM.

Attacher un disque à une VM

Ce scénario ne concerne pas New-AzureQuickVM.

Depuis le portail on dispose du menu ATTACH:

2015-04-06_13-22-04

Avec PowerShell on utilise la cmdlet Add-AzureDataDisk:

Get-AzureVM -ServiceName $serviceName -Name $vmName | Add-AzureDataDisk -Import -DiskName « monDisque » -Lun 1 | Update-AzureVM

Il ne reste plus qu’à constater que l’attachement a bien eu lieu en se connectant à la VM.

Add-AzureDataDisk accepte en réalité 3 modes de fonctionnement selon le paramètre choisit:

  • Import
  • CreateNew
  • ImportFrom

Import est le paramètre utilisé plus haut. Il indique que l’on importe un disque existant depuis la librairie des disques.

CreateNew demande de créer et attacher un nouveau disque vide. On devra ensuite l’initialise puis le formater.

ImportFrom importe un disque depuis un blob.

Le détail des paramétrages se trouve dans la doc:

https://msdn.microsoft.com/en-us/library/azure/dn495298.aspx

Note : On ne doit pas confondre Add-AzureDataDisk avec Add-AzureDisk qui sert à ajouter un disque dans le magasin de disques. Il suffit de se souvenir que dans le magasin on peut pousser des disques OS et des disques de données, tandis que dans la VM on ne peut attacher que des disques de données.

Création d’une VM depuis un disque

Le script de base est le suivant:

$vmConfig = New-AzureVMConfig -Name $vmName -InstanceSize $size –DiskName $osdiskName
$vmConfig | Add-AzureDataDisk -Import -DiskName $datadiskname -LUN 0
$vmConfig | New-AzureVM -ServiceName $serviceName -Location $location

Ce script est presque identique au précédent, la principale différence est l’utilisation dans New-AzureVMConfig de DiskName à la place d’ImageName. La propriété désigne un OS Disk.

Le script ajoute également un disque de données avec Add-AzureDataDisk et construit la VM.

Scénarios avancés

Configurer une VM avec un fichier

Il est possible de créer et configurer une VM sans cmdlets, simplement avec un fichier de configuration. Le plus pratique est de partir d’une VM existante et réclamer son fichier de configuration que l’on pourra personnaliser par la suite:

Export-AzureVM -ServiceName $serviceName -Name $vmName -Path « c:\temp\config.xml »

Cette commande exporte la configuration de la VM $vmName dans le fichier désigné par Path. Le fichier résultant ressemble à ceci:

2015-04-15_22-39-19

Il contient la description de tous les états de la VM.

On peut ensuite faire l’opération inverse.

Pour recréer la machine il faudra d’abord la supprimer:

Remove-AzureVM -Name $vmName  -ServiceName $serviceName

Note: on ne doit surtout pas supprimer le VHD!!!

Puis:

Import-AzureVM -Path « c:\temp\config.xml » | New-AzureVM -ServiceName $serviceName -WaitForBoot

On dispose ainsi d’un moyen simple de déplacer une VM d’un service vers un autre.

Bien sûr il n’y a aucune garantie de retrouver l’IP.

Ajouter un disque

Il est assez fréquent que l’on attache un disque à une VM existante. Pour créer un nouveau disque on dispose d’Add-AzureDataDisk:

$config | Add-AzureDataDiskCreateNew -DiskSizeInGB 10 -LUN 0 -DiskLabel « dataAmeth » | Update-AzureVM

Note: on oublie souvent la dernière commande: Update-AzureVM

On peut tester la création du disque:

Get-AzureDisk| where {$_.Label -eq « dataAmeth »}

Qui affiche les informations sur le disque:

2015-04-03_12-43-36

Il ne reste plus qu’à activer le disque avec DiskManager (en lançant diskmgmt.msc) et le formater pour qu’il soit prêt à l’emploi.

Gérer le domaine de disponibilité

Il est possible de placer ne VM dans un domaine de disponibilité (availability set) au moment de la création, où ultérieurement.

Dans l’alternative il faut avoir en tête que l’opération peut entrainer un reboot de la VM si Azure a besoin de la déplacer.

Le script suivant déploie 4 VM dans deux domaines contoso0 et contoso1 :


New-AzureService -ServiceName $serviceName -Location $location
$configs = @()
for($i=1; $i -le 4; $i++)
{
$index = $i % 2
$CurrentName = $vmName + $i
$Config = New-AzureVMConfig -Name $CurrentName -InstanceSize $size -AvailabilitySetName "contoso$index" -ImageName $imageName
$Config | Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd
$Configs += $Config
}
New-AzureVM -ServiceName $serviceName -VMs $configs

 

Si on se rend sur le portail on peut trouver ceci:

2015-04-13_22-39-52

Lançons maintenant le script suivant qui déplace les VM de contoso0 vers contoso1 :


$vms = get-azurevm -ServiceName $serviceName | where {$_.AvailabilitySetName -eq "contoso0"}

foreach($vm in $vms)
{
$vm | Set-AzureAvailabilitySet -AvailabilitySetName "contoso1" | Update-AzureVM
}

 

Et cette fois :

2015-04-13_22-41-24

Modifier la localisation des disques durs virtuelles

Le compte de stockage est utilisé pour stocker les fichiers vhd de données et d’OS dans un blob. Par défaut la création a lieu dans le conteneur vhds ce que l’on constate en regardant la propriété MediaLink:

2015-04-03_12-43-36

Dans laquelle demordpstorage est le nom du compte de stockage. On peut tout à fait personnaliser les localisations et le nom du disque dur virtuel. C’est utile pour établir une systématique de nommage utile afin de rendre lisible la configuration dans le cadre d’une organisation.

Voici un petit exemple:


$container="disques"
$storage="demordpstorage"

$osDisque="https://$storage.blob.core.windows.net/$container/os.vhd"
$dataDisque="https://$storage.blob.core.windows.net/$container/data1.vhd"

New-AzureService -ServiceName $serviceName -Location $location

$imageName = get-azurevmimage | where {$_.ImageFamily -eq $familyName}| sort PublishedDate -Descending|select -ExpandProperty ImageName -First 1
$config = new-azurevmconfig -Name $vmName -InstanceSize $size -ImageName $imageName -MediaLocation $osDisque

$config | Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd
$config | Add-AzureDataDisk -CreateNew -DiskSizeInGB 20 -LUN 0 -DiskLabel "dataAmeth2" -MediaLocation $dataDisque
$config | New-AzureVM -ServiceName $serviceName

 

La propriété à renseigner est MediaLocation. Observez comment elle est construite. Bien entendu $storage doit correspondre à un storage existant.

New-AzureVmConfig attend le stockage du disque OS.

2015-04-03_21-31-11

Déployer un certificat

Déployer un certificat est une opération utile pour configurer SSL par exemple. Le déploiement se fait au niveau du conteneur cloud service. On procède de cette façon:

 


$certPwd="XXXXXXXX"
$pfxFile="XXXXXXX.pfx"
$cert=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($pfxFile,$certPwd,'Exportable')

New-AzureService -ServiceName $serviceName -Location $location

$imageName = get-azurevmimage | where {$_.ImageFamily -eq $familyName}| sort PublishedDate -Descending|select -ExpandProperty ImageName -First 1

$config = new-azurevmconfig -Name $vmName -InstanceSize $size -ImageName $imageName
$config | Add-AzureProvisioningConfig -Windows -AdminUsername $user -Password $pwd -X509Certificates $cert
$config | New-AzureVM -ServiceName $serviceName

 

On peut aussi vouloir déployer son propre certificat pour faire du PowerShell Remoting:

 


$certPwd="XXXXX"
$pfxFile="XXXXXXXX.pfx"
$cert=New-Object System.Security.Cryptography.X509Certificates.X509Certificate2
$cert.Import($pfxFile,$certPwd,'Exportable')

Get-azureVM -ServiceName $serviceName -Name $vmName | Add-AzureProvisioningConfig -WinRMCertificate $cert -Windows | Update-AzureVM

 

Le certificat est passé non pas à X509Certificates , mais à WinRMCertificate.

http://michaelwasham.com/windows-azure-powershell-reference-guide/introduction-remote-powershell-with-windows-azure/

Arrêter/lancer une VM

Il y a deux façons d’arrêter une VM et les conséquences ne sont pas les même.

  1. On arrête de façon simple la VM
  2. On arrête et on réalloue les ressources Azure

Dans le dernier cas il y a des impacts et en particulier la perte de la VIP, mais d’un autre côté on n’a pas de facturation autre que le stockage des fichiers vhd.

Seul PowerShell ou l’arrêt du serveur depuis une session dans le serveur permet de stopper. Le portail réalloue les ressources.

 

Pour arrêter en réallouant les ressources:

Stop-AzureVM -ServiceName $serviceName -Name $vmName

Si la VM est la dernière du service la popup suivante s’ouvre:

2015-04-04_18-30-18

 

La perte de la VIP ne se produit qu’après l’arrêt de la dernière VM et heureusement! Si on ne souhaite pas voir cette fenêtre s’afficher ce qui est préférable pour un script:

Stop-AzureVM -ServiceName $serviceName -Name $vmNameForce

2015-04-04_18-33-58

On redémarre:

Start-AzureVM -ServiceName $serviceName -Name $vmName

Pour arrêter la VM sans désallouer les ressources la syntaxe est la suivante:

Stop-AzureVM -ServiceName $serviceName -Name $vmName –StayProvisioned

2015-04-04_18-39-11

Le script suivant arrête toutes les VM d’un service donné:


$vms = Get-AzureVM -ServiceName $serviceName
foreach ($vm in $vms)
{
if ($vm.InstanceStatus -eq "ReadyRole")
{
Stop-azureVM -ServiceName $serviceName -Name $vm.Name -Force
}
}

 

Supprimer une VM, un disque, un service…

On supprime un service ainsi:

Remove-AzureService -ServiceName $serviceName -Force

La cmdlet fonctionne comme la commande DELETE du portail. Les VM seront supprimées également, mais pas les vhd. Le script suivant fait un nettoyage complet.

Remove-AzureService -ServiceName $serviceName –DeleteAll -Force

Supprime aussi les disques et les vhd.

 

On peut supprimer une VM dans un service:

Remove-AzureVM -ServiceName $serviceName -Name $vmName –DeleteVHD

DeleteVHD indique de supprimer le vhd du blob, pas juste la ressource Azure.

 

Remove-AzureDisk supprime un disque du repository Azure.

Remove-AzureDisk -DiskName « XXXXXXX » -DeleteVHD

On peut ajouter facultativement DeleteVHD pour également supprimer le vhd du blob. Le nom du disque se trouve ici:

2015-04-07_09-38-38

On peut obtenir via PowerShell la liste des DiskName d’une VM donnée:

Get-AzureDisk | where {$_.AttachedTo.RoleName -eq $vmName -and $_.AttachedTo.HostedServiceName -eq $serviceName} | select -ExpandProperty DiskName

Pour que la commande soit opérationnelle on doit supprimer la VM.

 

De la même façon on peut supprimer une image:

Remove-AzureVMImage -ImageName $imageName -DeleteVHD 

On force aussi la suppression du vhd. On retrouve l’image en PowerShell:

Get-AzurevmImage | where {$_.ImageName -eq $imageName}

 

Pour finir, il est possible de supprimer un disque de données d’une VM avec Remove-AzureDataDisk. On commence par récupérer la liste des disques de données d’une VM:

$dataDisks = get-azurevm -ServiceName $servicename -Name $vmName |Get-AzureDataDisk

On supprime tous les disques de données:


$vm = get-azurevm -ServiceName $servicename -Name $vmName
$dataDisks = $vm |Get-AzureDataDisk
foreach($dataDisk in $dataDisks)
{
$vm | Remove-AzureDataDisk -LUN $dataDisk.Lun  -DeleteVHD | Update-AzureVM
}

 

Note: aucune de ces commandes n’est particulièrement rapide. Attendre donc quelques minutes pour voir le résultat complet

 

Publicités

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s