Fully unattended Windows 11 Pro build using Autounattend.xml, swtpm for TPM 2.0 emulation, and VirtIO drivers. Five PowerShell provisioners strip bloatware, telemetry, unused services, and apply performance tuning for a resource-constrained host. Output is a compressed QCOW2 image. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
140 lines
3.4 KiB
HCL
140 lines
3.4 KiB
HCL
packer {
|
|
required_plugins {
|
|
qemu = {
|
|
version = ">= 1.1.0"
|
|
source = "github.com/hashicorp/qemu"
|
|
}
|
|
}
|
|
}
|
|
|
|
variable "win_iso_path" {
|
|
type = string
|
|
description = "Absolute path to Windows 11 Pro ISO"
|
|
}
|
|
|
|
variable "win_iso_checksum" {
|
|
type = string
|
|
description = "SHA-256 checksum prefixed with 'sha256:'"
|
|
}
|
|
|
|
variable "virtio_iso_path" {
|
|
type = string
|
|
default = "virtio-win.iso"
|
|
description = "Path to VirtIO drivers ISO (downloaded by 'make virtio-iso')"
|
|
}
|
|
|
|
variable "swtpm_sock" {
|
|
type = string
|
|
description = "Unix socket path for swtpm TPM emulator (managed by build.sh)"
|
|
}
|
|
|
|
variable "vm_name" {
|
|
type = string
|
|
default = "windows11-lite"
|
|
}
|
|
|
|
variable "disk_size" {
|
|
type = number
|
|
default = 51200
|
|
description = "Virtual disk size in MB (default 50 GB)"
|
|
}
|
|
|
|
variable "memory" {
|
|
type = number
|
|
default = 4096
|
|
description = "RAM in MB allocated during build"
|
|
}
|
|
|
|
variable "cpus" {
|
|
type = number
|
|
default = 2
|
|
}
|
|
|
|
variable "output_directory" {
|
|
type = string
|
|
default = "output"
|
|
}
|
|
|
|
variable "winrm_password" {
|
|
type = string
|
|
default = "Packer1234!"
|
|
sensitive = true
|
|
description = "WinRM password used during build; must match Autounattend.xml"
|
|
}
|
|
|
|
variable "ovmf_code" {
|
|
type = string
|
|
default = "/usr/share/edk2/ovmf/OVMF_CODE.fd"
|
|
}
|
|
|
|
variable "ovmf_vars" {
|
|
type = string
|
|
default = "/usr/share/edk2/ovmf/OVMF_VARS.fd"
|
|
}
|
|
|
|
source "qemu" "windows11" {
|
|
vm_name = var.vm_name
|
|
iso_url = "file://${var.win_iso_path}"
|
|
iso_checksum = var.win_iso_checksum
|
|
output_directory = var.output_directory
|
|
|
|
disk_size = var.disk_size
|
|
memory = var.memory
|
|
cpus = var.cpus
|
|
|
|
machine_type = "q35"
|
|
efi_firmware_code = var.ovmf_code
|
|
efi_firmware_vars = var.ovmf_vars
|
|
|
|
# VirtIO for minimal overhead; network also VirtIO
|
|
disk_interface = "virtio-scsi"
|
|
net_device = "virtio-net"
|
|
disk_cache = "unsafe"
|
|
disk_compression = true # deflate QCOW2 at build time; ~20-30% smaller image
|
|
|
|
qemuargs = [
|
|
# Software TPM 2.0 via swtpm
|
|
["-chardev", "socket,id=chrtpm,path=${var.swtpm_sock}"],
|
|
["-tpmdev", "emulator,id=tpm0,chardev=chrtpm"],
|
|
["-device", "tpm-tis,tpmdev=tpm0"],
|
|
# VirtIO drivers ISO (drive letter assigned dynamically; Autounattend searches D-G)
|
|
["-drive", "file=${var.virtio_iso_path},media=cdrom,readonly=on,if=ide"],
|
|
# Absolute-position mouse so installer clicks land correctly without X11
|
|
["-device", "usb-tablet"],
|
|
]
|
|
|
|
# Autounattend.xml served on a small virtual CD; Windows Setup finds it automatically
|
|
cd_files = ["./http/Autounattend.xml"]
|
|
cd_label = "AUTOUNATTEND"
|
|
|
|
communicator = "winrm"
|
|
winrm_username = "Administrator"
|
|
winrm_password = var.winrm_password
|
|
winrm_timeout = "3h"
|
|
winrm_insecure = true
|
|
winrm_use_ssl = false
|
|
|
|
headless = true
|
|
boot_wait = "5s"
|
|
boot_command = ["<spacebar>"]
|
|
shutdown_command = "shutdown /s /t 10 /f /d p:4:1 /c \"Packer Shutdown\""
|
|
shutdown_timeout = "15m"
|
|
}
|
|
|
|
build {
|
|
name = "windows11-lite"
|
|
sources = ["source.qemu.windows11"]
|
|
|
|
provisioner "powershell" {
|
|
elevated_user = "Administrator"
|
|
elevated_password = var.winrm_password
|
|
scripts = [
|
|
"./scripts/01-debloat-apps.ps1",
|
|
"./scripts/02-disable-telemetry.ps1",
|
|
"./scripts/03-disable-services.ps1",
|
|
"./scripts/04-performance.ps1",
|
|
"./scripts/05-cleanup.ps1",
|
|
]
|
|
}
|
|
}
|