Ca faisait longtemps dites-moi ! Longtemps, en effet, que je n’avais pas posté de la bidouille technique ! Pour un vendredi, cela va vous rafraîchir un peu j’en suis sûr, après les nombreux billets plutôt marketingo-stratégiques et les annonces VMUGFR. Aujourd’hui, je vous propose un petit tutoriel qui concernera sans doute un public de niche, puisque je vais détailler un script PowerShell que j’ai construit et qui consiste à provisionner automatiquement un Virtual DataCenter sur vCloud Director et tout ce qu’il est sensé contenir, à savoir les réseaux internes, Edge Gateway, vApp, importation de VMs etc.
Ce travail de scripting fait suite à un projet d’hébergement régional dont nous avons la charge dans les semaines qui viennent. L’objectif, sans rentrer dans le détail, consiste à déployer un certain nombres d’environnements d’une quinzaine de machines virtuelles chacun. Ces environnements sont de type n-tier, utilisant des segments de réseau différents, dont l’interconnexion est assurée par une Edge Gateway filtrante. Globalement, nous avons au moins 4 bulles vCloud à déployer. Autant dire qu’un peu d’automatisation ne peut pas faire de mal ^^.
Le scripte PowerCLI suit une logique compatible avec les concepts de vCloud Director, à savoir :
– Création de l’Organisation et paramétrage
– Création du Virtual DataCenter et paramétrage (notamment vis à vis du Storage Profile)
– Création de la Edge Gateway
– Création des réseaux VDC connectés à cette Edge (7 segments au total)
– Création des vApp et ajout des réseaux utiles à chacune d’entre elles
– Importation des VMs dans les bonnes vApp et connexion réseau sur le bon segment
Même si l’ensemble du code est très dirigé vers l’objectif initial, il est sans problème ré-utilisable pour d’autres Use Cases et d’autres types d’architecture. Il peut donc servir facilement de base de travail pour d’autres chantiers. Ce sera à vous de vous en inspirer au besoin !
Paramètres sources
Tout le script s’appuie sur des paramètres de base définissant les règles de nommage et les connexions des éléments les uns avec les autres :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
$orgName = "Ma petite entreprise" $vdcName = "Mon datacenter" $providerVdcName = "GROZEBERGEUR" $netPoolName = "GROZEBERGEUR-VLAN-Pool" $gwName = "MPE_Edge" $gwExtNet = "GROZEBERGEUR_PoolInternet" $storProfName = "GROZBAIE" $gw_primaryIP = "1.1.1.254" $gw_rangeStart = "1.1.1.1" $gw_rangeEnd = "1.1.1.10" $netList = @( "prod-app 10.10.2.254 255.255.255.0", "prod-bdd 10.10.3.254 255.255.255.0", "test-app 10.10.5.254 255.255.255.0", "test-bdd 10.10.6.254 255.255.255.0", "prod-adm 10.10.7.254 255.255.255.0" ) $vAppList = @( "Adm", "Test", "Prod" ) $vAppNetList = @( "Adm prod-adm", "Test test-app", "Test test-bdd", "Prod prod-app", "Prod prod-bdd" ) # Tableau d'importation des VMs, les champs: # "nom-de-la-vm-source-a-importer nom-de-la-vm-dans-vcloud vapp-cible ip-static segment-reseau" $vmList = @( "monappadmprd-src monappadmprd Adm 10.10.7.11 prod-adm", "monappdepprd-src monappdepprd Adm 10.10.7.12 prod-adm", "monappbddprd-src monappbddprd Prod 10.10.3.10 prod-bdd", "monappdirprd-src monappdirprd Prod 10.10.2.10 prod-app", "monappiddprd-src monappiddprd Prod 10.10.2.12 prod-app", "monappideprd-src monappideprd Prod 10.10.2.11 prod-app", "monappbddtst-src monappbddtst Test 10.10.6.10 test-bdd", "monappdirtst-src monappdirtst Test 10.10.5.10 test-app", "monappiddtst-src monappiddtst Test 10.10.5.12 test-app", "monappidetst-src monappidetst Test 10.10.5.11 test-app" ) |
Les listes de VM, vApp, réseau ect, permettent d’assurer la cohérence et les connexions des éléments entre eux. Les champs son séparés par des espaces et splittés lors de leur parcours dans le code qui suit.
Création de l’organisation et du virtual datacenter
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
########################################################## # Connect CIServer et VIServer ########################################################## Connect-VIServer -Server monvsphere.local Connect-CIServer -Server monvcloud.local ########################################################## # Creation Orga + OrgVDC ########################################################## Write-Host "Creation de l'organisation" $orgName $org = New-Org -Name $orgName -FullName "Test provisionning auto" -Description "" # Changer les parametres de bail VM/Sto $paramBail = $org.ExtensionData.Settings.GetVAppLeaseSettings() $paramBail.DeploymentLeaseSeconds = 0 $paramBail.StorageLeaseSeconds = 0 $paramBail.DeleteOnStorageLeaseExpiration = $False $paramBail.UpdateServerData() $paramBail = $org.ExtensionData.Settings.GetVAppTemplateLeaseSettings() $paramBail.StorageLeaseSeconds = 0 $paramBail.DeleteOnStorageLeaseExpiration = $False $paramBail.UpdateServerData() Write-Host "Creation du VDC" $vdcName $orgvdc = New-OrgVdc -name $vdcName -AllocationModelPayAsYouGo -NetworkPool $netPoolName -Org $orgName -ProviderVDC $providerVdcName -VMCpuCoreMHz 2000 Set-OrgVdc -OrgVdc $orgvdc -CpuGuaranteedPercent 1 -MemoryGuaranteedPercent 1 -NetworkMaxCount 10 -ThinProvisioned $true -UseFastProvisioning $false -VMCpuCoreMHz 2200 -VMMaxCount $null # Récupération du storage profile $storageProf = search-cloud -QueryType ProviderVdcStorageProfile -Name $storProfName | Get-CIView # Creation des parametres pour intégrer le storage profile dans le VDC $paramStor = new-object VMware.VimAutomation.Cloud.Views.VdcStorageProfileParams $paramStor.Limit = 2048 $paramStor.Units = "GB" $paramStor.ProviderVdcStorageProfile = $storageProf[0].href $paramStor.Enabled = $true $paramStor.Default = $true $maj = new-object VMware.VimAutomation.Cloud.Views.UpdateVdcStorageProfiles $maj.AddStorageProfile = $paramStor # Ajout du nouveau storage profile dans le OrgVdc $orgVdc.ExtensionData.CreateVdcStorageProfile($maj) |
La création de l’organisation et du VDC ne posent pas de souci particulier. Leur paramétrage en revanche m’a pris pas mal de temps, car autant il existe des docs assez simples pour utiliser les directives PowerCLI, autant le paramétrage des objets vCloud nécessite pas mal de connaissance dans la structure de ceux-ci, ainsi que d’utiliser aussi les documents de référence de l’API elle-même. Pas forcément simple quand on débute :)
Création de la Edge Gateway
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
########################################################## # Création edge gateway avec paramètres minimums ########################################################## $extNet = Get-ExternalNetwork -Name $gwExtNet $gw = New-Object VMware.VimAutomation.Cloud.Views.Gateway $gw.Name = $gwName $gw.Configuration = New-Object VMware.VimAutomation.Cloud.Views.GatewayConfiguration $gw.Configuration.BackwardCompatibilityMode = $false $gw.Configuration.GatewayBackingConfig = "compact" $gw.Configuration.UseDefaultRouteForDnsRelay = $true $gw.Configuration.HaEnabled = $false $gw.Configuration.EdgeGatewayServiceConfiguration = New-Object VMware.VimAutomation.Cloud.Views.GatewayFeatures # Creation de l'interface externe $gw.Configuration.GatewayInterfaces = New-Object VMware.VimAutomation.Cloud.Views.GatewayInterfaces $gw.Configuration.GatewayInterfaces.GatewayInterface = New-Object VMware.VimAutomation.Cloud.Views.GatewayInterface $gw.Configuration.GatewayInterfaces.GatewayInterface[0].DisplayName = $gwExtNet $gw.Configuration.GatewayInterfaces.GatewayInterface[0].Network = $extNet.HRef $gw.Configuration.GatewayInterfaces.GatewayInterface[0].InterfaceType = "uplink" $gw.Configuration.GatewayInterfaces.GatewayInterface[0].UseForDefaultRoute = $true $gw.Configuration.GatewayInterfaces.GatewayInterface[0].ApplyRateLimit = $false $extSubnet = New-Object VMware.VimAutomation.Cloud.Views.SubnetParticipation $extSubnet.Gateway = $extNet.Gateway $extSubnet.Netmask = $extNet.Netmask $extSubnet.IpAddress = $gw_primaryIP $extSubnet.IpRanges = New-Object VMware.VimAutomation.Cloud.Views.IpRanges $extSubnet.IpRanges.IpRange = New-Object VMware.VimAutomation.Cloud.Views.IpRange $extSubnet.IpRanges.IpRange[0].StartAddress = $gw_rangeStart $extSubnet.IpRanges.IpRange[0].EndAddress = $gw_rangeEnd $gw.Configuration.GatewayInterfaces.GatewayInterface[0].SubnetParticipation = $extSubnet Write-Host "Creation de la Edge Gateway" $gwName $orgvdc.ExtensionData.CreateEdgeGateway($gw) |
La création de la Edge gateway est sans doute la partie qui m’a pris le plus de temps, car le code fait appel à de nombreux objets qu’il faut enchaîner correctement. Je me suis beaucoup aidé de threads au sein de la communauté VMware. Je vous mets toutes les références importantes dont je me suis inspiré en fin d’article. Aujourd’hui, je ne suis pas complètement satisfait du résultat car la partie déclaration des règles Firewall est encore trop artisanale pour que je vous la présente. Mais je ne désespère pas de vous faire un petit add-on d’ici quelques temps :)
Création des réseaux et connexion de ceux-ci sur la Edge Gateway
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
########################################################## # Provisionnement des 7 reseaux SRI ########################################################## $edgeGateway = Search-Cloud -QueryType EdgeGateway -Name $gwName foreach ($net in $netList) { $array = $net -split " " Write-Host "Ajout du reseau " $array[0] "/" $array[1] "/" $array[2] $network = New-Object VMware.VimAutomation.Cloud.Views.OrgVdcNetwork $network.EdgeGateway = $edgeGateway.Id $network.isShared = $false $network.Configuration = New-Object VMware.VimAutomation.Cloud.Views.NetworkConfiguration $network.Name = $array[0] $ipScope = New-Object VMware.VimAutomation.Cloud.Views.ipScope $ipScope.Gateway = $array[1] $ipScope.Netmask = $array[2] $network.Configuration.ipScopes = New-Object VMware.VimAutomation.Cloud.Views.IpScopes $network.Configuration.ipScopes.ipScope = $network.Configuration.ipScopes.ipScope + $ipScope $network.Configuration.FenceMode = "natRouted" $orgvdc.ExtensionData.CreateNetwork($network) Write-Host "Creation en cours ... on attends 30 secondes" sleep 30 } |
La encore, une fois que la source d’inspiration est trouvé et interprétée, la logique est relativement simple : on décrit les paramètres de base, on indique la référence à la Edge Gatway à laquelle le réseau est rattaché, et instancie. Vous noterez-ici que le tableau “netList” est utilisé en splittant chaque enregistrement de texte grâce au séparateur espace. Ensuite, chaque champ est utilisé pour le paramétrage.
Création des vApp et ajout, pour chacune, des réseaux VDC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
########################################################## # Creation vApp + connexion vdcNet + IP static ########################################################## foreach ($vApp in $vAppList) { Write-Host "Creation de la vApp" $vApp New-CIVApp -Name $vApp -OrgVdc $orgvdc } foreach ($cnxNet in $vAppNetList) { $array = $cnxNet -split " " Write-Host "Connexion du vdcnet" $array[1] "de la vApp" $array[0] $parentNet = Get-OrgVdcNetwork -Name $array[1] -Org $orgvdc New-CIVappNetwork -Direct -ParentOrgVdcNetwork $parentNet -VApp (Get-CIVapp -Name $array[0] -OrgVdc $orgvdc ) } |
Ici, on va utiliser respectivement les deux tableaux $vAppList et $vAppNetList qui vont permettre de constituer le schéma logique d’interconnexion des vApp. Vous devez en effet au préalable ajouter un réseau VDC au sein de la vApp pour pouvoir l’utiliser en suite et connecter des VMs sur celui-ci.
Import des VMs “template” au sein de vCloud Director
Enfin, on termine par la création des VMs dans vCloud.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
########################################################## # Import des VMs et connexion sur les bons réseaux ########################################################## foreach ($list in $vmList) { $array = $list -split " " Try { $theVM = Get-VM -Name $array[0] $theVApp = Get-CIVapp -OrgVdc $orgvdc -Name $array[2] Write-Host "Importation de la VM" $array[0] "vers" $array[1] "/ vApp:" $array[2] "vAppNetwork:" $array[4] "IP:" $array[3] Import-CIVApp -VM $theVM -VMName $array[1] -VApp $theVApp $nic = Get-CIVM -Name $array[1] -OrgVdc $orgvdc | Get-CINetworkAdapter $vAppNetwork = Get-CIVappNetwork -Name $array[4] -VApp $theVApp Set-CINetworkAdapter -NetworkAdapter $nic -Primary -ResetMACAddress -Connected $true -VAppNetwork $vAppNetwork -IPAddress $array[3] -IPAddressAllocationMode Manual } Catch { Write-Host "Erreur pendant la tentative d'import de " $array[0] } } |
Les VMs sont donc importées via copie des VMs sources, situées dans le vSphere support de vCloud Director. Une fois l’import terminé, on vient chercher la carte réseau de la machine et la connecter au bon segment de réseau.
Conclusion
Tout d’abord, je précise que ce script n’a pas vocation à être un cadre vraiment générique à toute automatisation d’un import vCloud. En effet, il est tout de même très orienté en matière de structure et adapté à l’architecture souhaitée (une seule Edge Gateway, plusieurs segments réseau, tous en VDC. On aurait pu utiliser aussi les réseaux de vApp, etc). D’autre part, sa présentation est sans doute assez “dirty” comme disent les anglais. Ceci dit, il permet aussi de voir comme il est facile (environ une journée de travail pour le mettre au point) de piloter un vSphere/vCloud pour réaliser des tâches rébarbatives et se simplifier la vie.
J’espère qu’il vous donnera l’envie, si vous n’avez pas déjà eu la curiosité, de vous y mettre. Ce sera d’autant plus facile pour ceux qui maîtrisent déjà PowerShell, évidemment ^^. Je suis à votre disposition dans les commentaires pour détailler certains points ou difficultés que j’ai pu avoir, au besoin.
Mes principales sources :
https://900footvm.wordpress.com/2014/06/03/creating-a-vcloud-director-organization-with-powercli/
https://communities.vmware.com/thread/578644
https://communities.vmware.com/thread/566044
https://code.vmware.com/forums?id=2530
et d’une manière générale : https://code.vmware.com/, une véritable bible pour tout développeur VMware !
4.5