β οΈ Full Disclosure: Parts of this documentation were lovingly crafted by our AI overlords. If you find instructions telling you to "simply quantum-entangle your VMs" or "reticulate the splines," that's on me. PRs welcome for corrections! π€π Another Disclaimer: This repo is a merger of examples found across the internet, Reddit, StackOverflow answers at 2 AM, and official docs that may or may not have made sense at the time. I've done my best to generalize everything for public consumption.
A streamlined Packer automation pipeline that builds VM templates across multiple hypervisors (currently KVM and VMware) with GitHub Actions doing the heavy lifting. Think of it as Infrastructure-as-Code meets "I'm tired of clicking through wizards."
Packer/
βββ .github/workflows/
β βββ packer.yml # The orchestration magic
βββ builds/
β βββ common/
β β βββ variables/
β β βββ KVM.pkrvars.hcl # KVM-specific vars
β β βββ VMware.pkrvars.hcl # VMware-specific vars
β βββ RHEL 9/
β β βββ common/ # Shared configs
β β βββ KVM/
β β β βββ image.pkr.hcl
β β β βββ variables.pkrvars.hcl
β β βββ VMware/
β β βββ image.pkr.hcl
β β βββ variables.pkrvars.hcl
β βββ RHEL 10/
β βββ Ubuntu 24.04/
β βββ Windows 11/
β β βββ common/
β β βββ KVM/
β β βββ VMware/
β β βββ scripts/
β β βββ image.pkr.hcl
β β βββ variables.pkrvars.hcl
β βββ Windows 2025/
βββ setup/
βββ kvm-server-setup.yml # Ansible playbook for KVM
βββ Makefile
βββ OVERVIEW.md
βββ QUICKSTART.md
- Common Variables (
builds/common/variables/) - Cloud-specific settings that apply across all OS builds - OS-Specific Builds (
builds/{OS}/{Cloud}/) - Each OS gets its own directory with cloud-specific subdirectories - Shared Configs (
builds/{OS}/common/) - OS-specific files shared between clouds - Setup Directory - Ansible playbooks and documentation for setting up your build infrastructure
π For detailed documentation on specific builds, check the README files under builds/ - each OS has its own quirks and config notes.
The workflow (packer.yml) kicks off in two ways:
- Automatic: Push changes to any
builds/**directory (except folders named like*-archivedor READMEs) - Manual: Use
workflow_dispatchto build specific OS/Cloud combos on-demand
The pipeline is clever enough to:
- Detect which OS/Cloud combinations changed
- Build only what's needed (no wasted cycles)
- Skip archived builds automatically (append
-archivedto any folder name to retire it)
# Auto-detects: "Oh, you changed Ubuntu 24.04/KVM? Let me build just that."
# Manual mode: "You want Windows 11 on VMware? Say no more."The setup job scans changed files and generates a dynamic build matrix, so you're never building more than necessary.
Here's where it gets interesting (and slightly hacky):
- VMware Builds: Uses
arc-packer- ARC (Actions Runner Controller) on Kubernetes for dynamic, scalable runners - KVM Builds: Uses
BareMetal2- A dedicated VM specific to KVM as Packer QEMU doesn't support remote execution (yet) π€·
- Caching Strategy:
- On
arc-packer: Uses shared/mnt/packer-cachefor ISOs and plugins (saves bandwidth) - Elsewhere: GitHub Actions cache for plugins and ISOs
- On
- Parallel Builds: Max 5 concurrent builds (
max-parallel: 5) - Fail-Fast Disabled: One build failing won't kill the others
- Secrets Management: Template and cloud credentials via GitHub Secrets
- Linux Password Hashing: Auto-generates secure hashed passwords for cloud-init
The pipeline sets these automagically:
PKR_VAR_template_password/PKR_VAR_template_username- Template VM credentialsPKR_VAR_vmware_password/PKR_VAR_vmware_username- VMware vCenter/ESXi credsPKR_VAR_hash_password- OpenSSL-hashed password for Linux cloud-init
- β RHEL 9.7 (KVM & VMware)
- β RHEL 10.1 (KVM & VMware)
- β Ubuntu 24.04 (KVM & VMware)
- β Windows 11 (KVM & VMware)
- β Windows 2025 (KVM & VMware)
The structure is deliberately simple:
- Add a new OS folder under
builds/ - Create
KVM/and/orVMware/subdirectories - Drop in your
image.pkr.hclandvariables.pkrvars.hcl - Push. The pipeline handles the rest.
Want to add Proxmox? Azure? AWS? Just add the cloud-specific config to builds/common/variables/ and create the corresponding subdirectories.
- GitHub repository with Actions enabled
- GitHub Secrets configured:
TEMPLATE_PASSWORD- Password for template VMsTEMPLATE_USERNAME- Username for template VMsVMWARE_PASSWORD- vCenter/ESXi password (if using VMware)VMWARE_USERNAME- vCenter/ESXi username (if using VMware)
- Build infrastructure:
- For VMware: ARC on Kubernetes cluster
- For KVM: Dedicated VM with nested virtualization enabled
See the setup/ directory for Ansible playbooks and detailed documentation:
QUICKSTART.md- Get up and running fastOVERVIEW.md- Deep dive into the setupkvm-server-setup.yml- Automated KVM host provisioning
Want to build a specific combo without waiting for a git push?
- Go to Actions β Packer Changed Builds
- Click Run workflow
- Select your OS and Cloud platform
- Watch the magic happen β¨
Just push changes to any build directory:
# This will trigger Ubuntu 24.04 KVM build
vim builds/Ubuntu\ 24.04/KVM/image.pkr.hcl
git commit -am "Updated Ubuntu KVM config"
git pushRetiring an old OS version? Just rename it:
mv "builds/Ubuntu 22.04" "builds/Ubuntu 22.04-archived"
git commit -am "Archived Ubuntu 22.04"
git pushThe pipeline will ignore it forever (or until you un-archive it).
builds/common/variables/- Cloud provider settings (datastore paths, networks, etc.)builds/{OS}/common/- OS-specific files used by both clouds (scripts, configs, etc.)
The setup/ directory contains everything you need to bootstrap a KVM build server:
- Ansible-based provisioning
- Dependency installation
- Libvirt/QEMU configuration
- Storage pool setup
- Check if virtualization is enabled in BIOS (especially for KVM)
- Verify GitHub Secrets are configured correctly
- Look at the Packer logs - they're verbose for a reason
- Make sure your
BareMetalrunner has enough CPU/RAM - Check if nested virtualization is properly enabled
- Consider dedicating more cores to the build VM
- Add cloud-specific variables to
builds/common/variables/{Cloud}.pkrvars.hcl - Update the GitHub Actions workflow to recognize the new cloud
- Create OS builds under
builds/{OS}/{Cloud}/ - Optionally add a runner selection rule in the workflow
Found a bug? Want to add support for another OS or cloud? PRs welcome!
Just remember: if the AI wrote something dumb in the docs, you're now part of the solution π
Use it, break it, fix it, fork it. No warranty expressed or implied. If your VMs achieve sentience, that's between you and them.
Pro Tip: Start with the QUICKSTART.md in the setup/ directory if you're setting this up from scratch.