VMware vSphere : comment utiliser Packer pour créer un modèle de VM Windows Server 2022 ?
Sommaire
I. Présentation
Dans ce tutoriel, nous allons voir comment créer un template Windows Server 2022 pour VMware vSphere, de façon automatique grâce à l’utilisation de l’outil Packer.
Ce template généré avec Packer sera exporté dans une bibliothèque de contenu (Content Library). Ainsi, nous aurons un modèle de VM prêt à l'emploi sur notre vSphere. Cette démonstration est réalisée à partir d’un poste Windows 10 et VMware vSphere 8 pour l'infrastructure de virtualisation.
Pour suivre cet article, vous avez besoin :
- D’une architecture VMware vShpere (ESXi et vCenter)
- De Packer sur une machine
- Des bases en YAML, même si ce n’est pas indispensable
Avant de suivre cet article, et si vous débutez avec Packer, nous vous recommandons de lire l’article suivant :
Qu’est-ce qu’une bibliothèque de contenu dans vSphere ?
Dans vSphere, une Content Library est une fonctionnalité qui permet de stocker, organiser et gérer des fichiers et des modèles de machines virtuelles (VM) de manière centralisée. Cela facilite la distribution et le déploiement de VM, ainsi que la gestion des mises à jour et des versions.
Un Content Library peut contenir différents types de contenu, tels que des fichiers ISO, des fichiers de script, des modèles de VM, des fichiers OVF (Open Virtualization Format), des images de disque, etc. Ces éléments peuvent être stockés localement sur un serveur vSphere ou sur un dépôt distant accessible via HTTP(S), FTP ou NFS.
L'intérêt principal d'une Content Library est la centralisation et la gestion simplifiée du contenu lié aux VM. Voici quelques avantages spécifiques :
- Distribution facile : vous pouvez partager le contenu de la bibliothèque avec d'autres utilisateurs, équipes ou sites. Cela facilite la distribution cohérente des fichiers et des modèles de VM dans un environnement vSphere.
- Déploiement rapide : en utilisant une bibliothèque de contenu, vous pouvez déployer rapidement des machines virtuelles à partir de modèles préconfigurés. Cela permet d'accélérer le processus de provisionnement des VM et de garantir une cohérence dans les configurations.
- Gestion centralisée : une Content Library vous permet de gérer et de mettre à jour facilement les fichiers et les modèles de VM. Vous pouvez contrôler les versions, les autorisations d'accès et suivre les modifications apportées au contenu.
- Facilité de mise à jour : si vous devez mettre à jour un modèle de VM ou un fichier commun utilisé par plusieurs VM, vous pouvez le faire directement dans la bibliothèque. Les changements seront répercutés automatiquement sur toutes les VM qui utilisent ce contenu.
- Haute disponibilité : vous pouvez configurer la réplication de la bibliothèque de contenu pour assurer la disponibilité du contenu sur plusieurs sites vSphere. Cela garantit que le contenu est accessible même en cas de panne d'un site.
II. Le cas pratique du jour
Même s'il a déjà été évoqué en introduction, voici quelques précisions.
Nous allons vous montrer comment utiliser Packer pour créer une image Windows Server 2022 contenant les VMware Tools et construite à partir du fichier ISO du système. Ce processus est très simple. Packer sera utilisé pour construire un modèle (template) qui sera stocké dans une bibliothèque de contenu sur vSphere.
L'avantage d'un modèle est qu'il apporte de la cohérence dans l'administration des machines virtuelles (VM) sur vSphere en utilisant une configuration de base. Ce format est immuable, ce qui en fait une solution idéale pour conserver les mêmes paramètres, quel que soit le déploiement.
Une fois le modèle créé, vous pouvez le déployer manuellement ou lancer un déploiement automatique en utilisant des outils tels que Terraform ou Ansible.
Cette approche est couramment utilisée dans le cloud, où il est essentiel de maintenir une cohérence entre les VM et de réaliser des déploiements rapides. En effet, un modèle est simplement une VM préconfigurée stockée dans un format spécifique qui empêche toute modification ultérieure.
Nous allons utiliser le provider "vsphere-iso" de Packer, qui permet de déployer un template à partir d’un fichier ISO. Toutefois, si vous voulez simplement mettre à jour vos templates, vous pouvez utiliser le provider "vsphere-clone".
Quelques précisions sur le builder "vsphere-iso" :
- Ce builder utilise un processus d'installation classique pour créer une image de machine virtuelle à partir d'un ISO (fichier d'image disque) de l'OS souhaité. Il crée une nouvelle machine virtuelle à partir de zéro et installe l'OS en utilisant l'ISO spécifié.
- Il offre une flexibilité totale pour personnaliser l'installation de l'OS selon vos besoins spécifiques. Vous pouvez définir des paramètres de configuration, exécuter des scripts de post-installation, installer des logiciels supplémentaires, etc.
- Ce builder est utile lorsque vous avez besoin de créer des images de machine virtuelle à partir de zéro avec un contrôle total sur le processus d'installation.
Quelques précisions sur le builder "vsphere-clone" :
- Ce builder utilise une machine virtuelle existante comme modèle (template) pour créer une nouvelle image de machine virtuelle par clonage. Il ne nécessite pas d'ISO car il se base sur une machine virtuelle déjà configurée et prête à l'emploi.
- Il est plus rapide que vsphere-iso car il évite le processus d'installation complet de l'OS. Il se contente de cloner une machine virtuelle existante, ce qui est généralement plus rapide.
- Cependant, il offre moins de flexibilité que vsphere-iso en termes de personnalisation de l'installation de l'OS. Les configurations et les logiciels supplémentaires doivent être préinstallés sur la machine virtuelle modèle.
III. Générer la VM avec Packer
A. Une configuration Packer basée sur trois fichiers
Pour les fichiers déclaratifs de Packer, nous allons utiliser le format HCL (Hashicorp Configuration Language). Toutefois, il faut garder à l’esprit que JSON est tout aussi utilisé puisqu’il peut être généré par les machines (au contraire du HCL qui sert surtout à la compréhension humaine). C’est pour cela que Packer intègre un outil json_2_HCL pour faciliter le passage du format JSON vers HCL.
Pour plus de sécurité dans un environnement DevOps (avec journalisation), nous allons séparer nos déclarations de variables de leur initialisation pour stocker des identifiants (ce n’est pas encore idéal, mais au moins on peut commiter sans transmettre les mots de passe avec notre .gitignore).
Nous allons donc avoir :
- Un fichier windows2022.pkr.hcl qui contiendra toute la configuration de notre VM Windows,
- Un fichier variables.pkr.hcl qui contiendra la déclaration de nos variables
- Un fichier windows2022.auto.pkrvars.hcl qui sera automatiquement inclus lors de notre build grâce à la présence du terme « auto » dans le nom
Tous ces fichiers sont disponibles sur mon repo GitHub :
Il faut savoir que lors de la commande « packer build . », l’outil concatène tous les fichiers .pkr.hcl ensemble pour en faire un entier. La séparation des fichiers n’étant utile que pour la sécurité, la flexibilité et la compréhension.
B. Les variables avec Packer
Une variable doit être déclarée avant d’être initialisée (comme en C++). Pour déclarer une variable, on peut le faire dans le fichier main ou dans un fichier séparé (e.g vars.pkr.hcl) et on peut lui passer plusieurs options :
- Type: spécification du type de la variable (string, bool, int, etc.)
- Valeur par défaut: valeur par défaut qui peut être surchargée par une initialisation en dehors de la déclaration
- Description: explication du but de la variable pour mieux comprendre à quoi elle sert
- Obligatoire: indication si la variable a un caractère obligatoire ou non (required), au format booléen
Exemple :
variable "nom_variable" { type = "string" # type de la variable (string, bool, int, etc.) default = "valeur_par_défaut" description = "description_de_la_variable" required = true # spécifie si la variable est requise }
Cette variable peut être surchargée si l'on fait :
nom_variable = "Autre valeur"
Ce qui permet de définir une valeur personnalisée pour la variable.
C. Validation et exécution
Une fois que tous nos fichiers .pkr.hcl sont bien écrits, Packer fournit un outil de validation qui permet de vérifier la configuration (chaque variable utilisée est bien déclarée, pas de mauvaise écriture de code, etc.).
Avec une console, on se positionne dans le répertoire où se situent nos fichiers HCL de Packer pour cette configuration, et on exécute :
packer validate .
Si la commande retourne "The configuration is valid", c'est parfait.
Voici le fichier "windows2022.pkr.hcl" et quelques explications à son sujet. Je rappelle que tous les fichiers et scripts sont sur mon GitHub.
locals { build_by = "Built by: HashiCorp Packer ${packer.version}" build_date = formatdate("YYYY-MM-DD hh:mm ZZZ", timestamp()) build_version = formatdate("MMDD.hhmm", timestamp()) } source "vsphere-iso" "WS2022" { // Nom de la VM et système invité (Windows Server 2022) vm_name = "WS2022" guest_os_type = "windows2019srvnext-64" version = "20" // Config de la machine CPUs = "${var.vmCpuNum}" RAM = "${var.vmMemSize}" cluster = "${var.vsphereCluster}" disk_controller_type = ["lsilogic-sas"] firmware = "bios" network_adapters { network = "${var.vsphereNetwork}" network_card = "vmxnet3" } storage { disk_size = "${var.vmDiskSize}" disk_thin_provisioned = true } remove_cdrom = "true" // ISO Source et checksum (Get-FileHash) // Le path peut être soit local, soit sur le vSphere dans un datastore iso_paths = ["${var.vSphereIsoPath}"] # "[Datastore] Dossier/fichier.iso" iso_checksum = "md5:290B43B5A6FE9B52B561D34EB92E8003" # à modifier selon votre iso // Config sur vSphere datacenter = "${var.vsphereDatacenter}" datastore = "${var.vsphereDatastore}" folder = "${var.vsphereFolder}" # cluster = "${var.vspherecluster}" notes = "Version: v${local.build_version}\nBuilt on: ${local.build_date}\n${local.build_by}" // Config de connexion à vSphere username = "${var.vsphereUser}" password = "${var.vspherePassword}" vcenter_server = "${var.vsphereServer}" // Décommenter cette option si vous n'avez pas de certificat sur votre vCenter # insecure_connection = "true" // Dossier contenant les scripts (sera monté en A:\) floppy_files = ["${var.floppyInitPath}"] // Config WinRM communicator = "winrm" winrm_username = "Administrateur" winrm_password = "${var.vmPassword}" winrm_insecure = true winrm_timeout = "30m" // Config Bibliothèque de contenu content_library_destination { library = "${var.CL}" ovf = "true" } // Commande pour arrêter le système (ici, on effectue un SYSPREP avant l'arrêt) // arrêt seul : shutdown_command = "shutdown /s /t 30 /f" shutdown_command = "C:\\Windows\\system32\\Sysprep\\sysprep.exe /generalize /oobe /shutdown /unattend:a:\\sysprep-autounattend.xml" shutdown_timeout = "60m" } build { sources = ["source.vsphere-iso.WS2022"] // Installer PowerShell (dernière version disponible sur GitHub) provisioner "powershell" { script = "${path.root}/setup/install-powershell.ps1" } // Initier un redémarrage de la machine provisioner "windows-restart" { restart_timeout = "10m" } }
En explorant notre fichier de configuration, nous constatons la présence du bloc "source" qui sert à définir la configuration de la VM et de l'environnement cible. Ensuite, Packer utilisera le protocole WinRM pour se connecter à la machine virtuelle. Cela permettra d'exécuter des commandes PowerShell à distance et de fournir une configuration supplémentaire à la VM.
Pour faciliter cette configuration, un lecteur de disquette virtuel sera monté sur la machine virtuelle avec le contenu du répertoire "setup" situé à la racine du projet "VM-WS2022". Ce répertoire contient le fichier autounattend.xml, qui spécifie les réponses automatiques à fournir lors de l'installation de Windows Server 2022, ainsi que le script winrmConfig.ps1 qui permet d'activer et de configurer WinRM sur la VM. Ces éléments sont essentiels pour automatiser la configuration de la VM une fois qu'elle est créée.
La section suivante, intitulée "build", indique les étapes supplémentaires à exécuter après la création de la VM. Dans cet exemple, nous utilisons deux provisioners PowerShell pour exécuter des scripts. Ceux-là sont présents dans le fichier “setup” que nous avons fourni au départ. Nous les utilisons pour configurer ce dont nous avons besoin sur la machine Windows.
Cette méthode est à privilégier par rapport à une exécution de script directement dans l’autounattend.xml comme on peut le trouver des fois. En effet, Packer permet de voir les erreurs d’exécution des scripts des provisioners puisqu’il les lance à partir de WinRM alors que dans l’autre cas Packer n’a aucune visibilité sur ce qu'il se passe. Enfin, si les scripts prenaient trop de temps à s’exécuter via l’autounattend, Packer aurait un timeout car la connexion winRM ne s’ouvrirait pas assez vite, alors que si les provisioners s’exécutent, Packer peut identifier les erreurs et n’a pas de limite de timeout.
Enfin, une fois que toutes les étapes de configuration sont terminées, Packer générera une image de la VM dans la bibliothèque de contenu spécifiée dans la section "content_library_destination". Cette image pourra ensuite être déployée sur d'autres environnements vSphere en utilisant cette bibliothèque de contenu.
D. Transfert dans une Content Library de vSphere
Lorsque l'on a vérifié que l'image générée par Packer était correcte, on peut transférer cette image vers notre bibliothèque de contenus vSphere.
Pour que Packer transfère automatiquement l'image générée dans la bibliothèque de contenus de vSphere, il faut déclarer une content library dans le bloc source. Ce qui correspond aux lignes suivantes dans le fichier ci-dessus :
// Config Bibliothèque de contenu
content_library_destination {
library = "${var.CL}"
ovf = "true"
}
On spécifie la variable qui contient le chemin de notre CL et on demande à Packer de créer un template OVF et non une VM template. Ce format est plus utile puisque plus facile à exporter (par exemple si on devait tester la VM sur VMware Workstation).
Pour lancer la construction de l'image, nous allons utiliser la commande classique (à exécuter dans le répertoire où se situe nos fichiers HCL de Packer) :
packer.exe build .
L'opération s'est bien déroulée. La suite se passe dans vSphere directement !
IV. Déploiement d'une VM à partir de notre modèle vSphere
Une fois que l’on a notre template de généré, il nous suffit de le déployer à partir de vSphere. Il faut donc se rendre dans l’onglet "Bibliothèque de contenus" via l'interface vSphere :
On sélectionne ensuite notre bibliothèque de contenus de templates :
Et on retrouve nos templates au format OVF, parmi lesquels celui qui vient d'être généré par Packer !
De là à déployer une VM à partir de ce template, il n’y a que trois clics : on sélectionne le template, puis dans "Actions" on sélectionne "Nouvelle VM à partir du template".
V. Conclusion
On arrive (malheureusement) à la fin de cet article. On pourrait aller beaucoup plus loin avec une gestion dynamique de la configuration du template avec des pipelines CI/CD, un déploiement facilité avec Terraform, un provisioning avec Ansible... Nous devrions aborder ces sujets dans de prochains articles !
La bonne nouvelle, c'est que désormais vous savez créer un modèle de VM Windows Server 2022 pour VMware vSphere en utilisant Packer !