Build multi-edition¶
Templates Packer HCL pour Windows Server 2022 et variante Windows 10/11 BYOL. Build, validation et déploiement.
Structure Packer¶
packer/
├── variables.pkr.hcl # Variables communes
├── windows-server-vdi.pkr.hcl # Source Server 2022
├── windows-byol-vdi.pkr.hcl # Source Win 10/11 BYOL
└── vdi-win.auto.pkrvars.hcl # Valeurs par defaut
Variables communes¶
Créez packer/variables.pkr.hcl :
variable "project_id" {
type = string
description = "ID du projet GCP"
}
variable "zone" {
type = string
default = "europe-west1-b"
description = "Zone GCE pour le build"
}
variable "machine_type" {
type = string
default = "e2-standard-4"
description = "Type de machine pour le build"
}
variable "universe_domain" {
type = string
default = "googleapis.com"
description = "Universe domain GCP"
}
variable "profile" {
type = string
default = "full"
description = "Profil Ansible (developer, office, full)"
}
variable "disk_size" {
type = number
default = 50
description = "Taille du disque en Go (50 Go minimum pour Windows)"
}
Template Windows Server 2022¶
Créez packer/windows-server-vdi.pkr.hcl :
packer {
required_plugins {
googlecompute = {
version = ">= 1.1.0"
source = "github.com/hashicorp/googlecompute"
}
ansible = {
version = ">= 1.1.0"
source = "github.com/hashicorp/ansible"
}
}
}
source "googlecompute" "windows-server-vdi" {
project_id = var.project_id
zone = var.zone
source_image_family = "windows-2022"
source_image_project_id = "windows-cloud"
machine_type = var.machine_type
disk_size = var.disk_size
disk_type = "pd-ssd"
image_name = "vdi-win-server-${var.profile}-{{timestamp}}"
image_family = "vdi-win-server-${var.profile}"
image_description = "VDI Windows Server 2022 - profil ${var.profile}"
universe_domain = var.universe_domain
communicator = "winrm"
winrm_username = "packer_user"
winrm_insecure = true
winrm_use_ssl = true
winrm_timeout = "10m"
tags = ["packer-build"]
metadata = {
sysprep-specialize-script-ps1 = file("../scripts/setup-winrm.ps1")
}
}
build {
sources = ["source.googlecompute.windows-server-vdi"]
provisioner "ansible" {
playbook_file = "../ansible/playbook.yml"
user = "packer_user"
use_proxy = false
extra_arguments = [
"--extra-vars", "ansible_winrm_server_cert_validation=ignore profile=${var.profile}"
]
}
provisioner "file" {
source = "../scripts/unattend.xml"
destination = "C:\\scripts\\unattend.xml"
}
provisioner "powershell" {
script = "../scripts/sysprep.ps1"
}
}
Variante Windows 10/11 BYOL¶
Sole-Tenant Nodes
L'utilisation de licences Windows BYOL sur GCP nécessité des Sole-Tenant Nodes. Le coût est significativement plus élevé qu'une licence incluse.
Préparer l'image BYOL¶
- Télécharger l'ISO Windows 10/11 Enterprise depuis votre portail VLSC
- Créer un disque virtuel et installer Windows
- Importer l'image dans GCP :
gcloud compute images import vdi-win11-base \
--source-file=gs://MON-BUCKET/windows11-enterprise.vmdk \
--os=windows-11-x64-byol \
--project=MON-PROJET-ID
Template BYOL¶
Créez packer/windows-byol-vdi.pkr.hcl :
packer {
required_plugins {
googlecompute = {
version = ">= 1.1.0"
source = "github.com/hashicorp/googlecompute"
}
ansible = {
version = ">= 1.1.0"
source = "github.com/hashicorp/ansible"
}
}
}
source "googlecompute" "windows-byol-vdi" {
project_id = var.project_id
zone = var.zone
source_image = "vdi-win11-base"
source_image_project_id = var.project_id
machine_type = var.machine_type
disk_size = var.disk_size
disk_type = "pd-ssd"
image_name = "vdi-win-byol-${var.profile}-{{timestamp}}"
image_family = "vdi-win-byol-${var.profile}"
image_description = "VDI Windows 10/11 BYOL - profil ${var.profile}"
universe_domain = var.universe_domain
communicator = "winrm"
winrm_username = "packer_user"
winrm_insecure = true
winrm_use_ssl = true
winrm_timeout = "10m"
node_affinity {
key = "compute.googleapis.com/node-group-name"
operator = "IN"
values = ["MON-NODE-GROUP"]
}
tags = ["packer-build"]
metadata = {
sysprep-specialize-script-ps1 = file("../scripts/setup-winrm.ps1")
}
}
build {
sources = ["source.googlecompute.windows-byol-vdi"]
provisioner "ansible" {
playbook_file = "../ansible/playbook.yml"
user = "packer_user"
use_proxy = false
extra_arguments = [
"--extra-vars", "ansible_winrm_server_cert_validation=ignore profile=${var.profile}"
]
}
provisioner "file" {
source = "../scripts/unattend.xml"
destination = "C:\\scripts\\unattend.xml"
}
provisioner "powershell" {
script = "../scripts/sysprep.ps1"
}
}
Valeurs des variables¶
Créez packer/vdi-win.auto.pkrvars.hcl :
project_id = "MON-PROJET-ID"
zone = "europe-west1-b"
universe_domain = "my-universe.gcp.example.com"
profile = "developer"
Ne pas commiter vos valeurs
Ajoutez *.auto.pkrvars.hcl a votre .gitignore. Commitez un fichier vdi-win.auto.pkrvars.hcl.example avec des placeholders.
Lancer le build¶
Initialisation¶
Server 2022 — profil developer¶
Server 2022 — profil office¶
BYOL — profil full¶
Matrice de build¶
| Edition | Profil | Image famille | Durée estimée |
|---|---|---|---|
| Server 2022 | developer | vdi-win-server-developer | 25-35 min |
| Server 2022 | office | vdi-win-server-office | 20-25 min |
| Server 2022 | full | vdi-win-server-full | 30-40 min |
| Win 10/11 BYOL | developer | vdi-win-byol-developer | 25-35 min |
| Win 10/11 BYOL | office | vdi-win-byol-office | 20-25 min |
| Win 10/11 BYOL | full | vdi-win-byol-full | 30-40 min |
Validation post-build¶
Vérifier les images¶
gcloud compute images list --filter="family:vdi-win-" --format="table(name, family, status, creationTimestamp)"
Déployer une instance de test¶
gcloud compute instances create test-vdi-windows \
--image-family=vdi-win-server-developer \
--machine-type=e2-standard-4 \
--zone=europe-west1-b \
--boot-disk-size=50GB
Connexion RDP¶
Cette commande retourné l'adresse IP, le nom d'utilisateur et le mot de passe pour la connexion RDP.
Vérification manuelle¶
Une fois connecte en RDP, verifiez :
- Bureau Windows personnalise
- LibreOffice / M365 fonctionne
-
nerdctl run --rm mcr.microsoft.com/windows/nanoserver:ltsc2022 cmd /c echo ok -
wsl -d Ubuntu -- docker run --rm hello-world -
kubectl get nodesretourné un nœud Ready - Windows Defender actif, firewall actif
Nettoyage¶
gcloud compute instances delete test-vdi-windows --zone=europe-west1-b --quiet
gcloud compute images delete vdi-win-server-developer-TIMESTAMP --quiet
Troubleshooting¶
| Erreur | Cause | Solution |
|---|---|---|
WinRM connection timeout | Script bootstrap pas exécuté | Vérifier metadata.sysprep-specialize-script-ps1 |
Ansible unreachable | pywinrm manquant | pip install pywinrm |
Sysprep failed | Image déjà generalisee | Rebuilder depuis l'image de base |
WSL install failed | Feature pas activee | Vérifier VirtualMachinePlatform feature |
containerd service failed | Feature Containers manquante | Vérifier win_feature: Containers |
K3s not starting | systemd pas active dans WSL2 | Vérifier /etc/wsl.conf contient systemd=true |
Windows Update timeout | VM trop lente | Augmenter reboot_timeout a 1800 |
Préparation pour Guacamole¶
L'image est prete pour être utilisée avec Apache Guacamole (Tuto 4). Le protocole RDP est le seul prérequis côté VDI. Guacamole se connectera sur le port RDP configuré (par défaut 3389).
Prochaine étape
Le Tutoriel 4 — Passerelle Guacamole couvre le déploiement d'Apache Guacamole pour accéder aux VDI Windows et Linux via un navigateur web.