This guide covers the Windows-host workflow for Ubuntu Hyper-V with the Dev Alchemy CLI:
- Build the box (
alchemy build) - Create/start the VM (
alchemy create) - Provision with Ansible (
alchemy provision)
All commands are intended for PowerShell on a Windows host.
Managed Dev Alchemy paths on Windows default to:
- App data root:
%LOCALAPPDATA%\dev-alchemy - Build cache:
%LOCALAPPDATA%\dev-alchemy\cache - Vagrant state:
%LOCALAPPDATA%\dev-alchemy\.vagrant
Set DEV_ALCHEMY_APP_DATA_DIR if you want to override the default root.
- Run the dependency installer from repository root in an elevated PowerShell session:
alchemy.exe installRun from repository root:
# server
alchemy.exe build ubuntu --type server --arch amd64
# desktop
alchemy.exe build ubuntu --type desktop --arch amd64Expected artifacts:
%LOCALAPPDATA%\dev-alchemy\cache\ubuntu\hyperv-ubuntu-server-amd64.box%LOCALAPPDATA%\dev-alchemy\cache\ubuntu\hyperv-ubuntu-desktop-amd64.box
Set a Hyper-V switch to avoid interactive selection:
$env:VAGRANT_HYPERV_SWITCH = "Default Switch"Then create/start with the wrapper:
# server
alchemy.exe create ubuntu --type server --arch amd64
# desktop
alchemy.exe create ubuntu --type desktop --arch amd64Default guest credentials:
- Username:
packer - Password:
P@ssw0rd!
Do not create inventory/hyperv_ubuntu.yml manually.
The wrapper discovers the VM IP and passes an inline inventory host to Ansible.
Run provisioning from repository root:
# server
alchemy.exe provision ubuntu --type server --arch amd64 --check
alchemy.exe provision ubuntu --type server --arch amd64
# desktop
alchemy.exe provision ubuntu --type desktop --arch amd64 --check
alchemy.exe provision ubuntu --type desktop --arch amd64Optional .env / environment overrides:
HYPERV_UBUNTU_ANSIBLE_USER=packer
HYPERV_UBUNTU_ANSIBLE_PASSWORD=P@ssw0rd!
HYPERV_UBUNTU_ANSIBLE_BECOME_PASSWORD=P@ssw0rd!
HYPERV_UBUNTU_ANSIBLE_CONNECTION=ssh
HYPERV_UBUNTU_ANSIBLE_SSH_COMMON_ARGS=-o StrictHostKeyChecking=no -o ServerAliveInterval=10 -o ServerAliveCountMax=3 -o ControlMaster=no -o ControlPersist=no
HYPERV_UBUNTU_ANSIBLE_SSH_TIMEOUT=120
HYPERV_UBUNTU_ANSIBLE_SSH_RETRIES=3Optional Cygwin shell override:
$env:CYGWIN_BASH_PATH = "C:\tools\cygwin\bin\bash.exe"
# or
$env:CYGWIN_TERMINAL_PATH = "C:\tools\cygwin\bin\mintty.exe"If you want to run Vagrant directly:
$AppDataDir = if ($env:DEV_ALCHEMY_APP_DATA_DIR) { $env:DEV_ALCHEMY_APP_DATA_DIR } else { Join-Path $env:LOCALAPPDATA "dev-alchemy" }
$CacheDir = Join-Path $AppDataDir "cache"
$VagrantRoot = Join-Path $AppDataDir ".vagrant"
$type = "server" # or "desktop"
$env:VAGRANT_BOX_NAME = "linux-ubuntu-$type-packer"
$env:VAGRANT_VM_NAME = "linux-ubuntu-$type-packer"
$env:VAGRANT_DOTFILE_PATH = Join-Path $VagrantRoot $env:VAGRANT_VM_NAME
vagrant box add $env:VAGRANT_BOX_NAME (Join-Path $CacheDir "ubuntu\hyperv-ubuntu-$type-amd64.box") --provider hyperv --force
cd deployments\vagrant\linux-ubuntu-hyperv
vagrant up --provider hyperv
cd ..\..\..$AppDataDir = if ($env:DEV_ALCHEMY_APP_DATA_DIR) { $env:DEV_ALCHEMY_APP_DATA_DIR } else { Join-Path $env:LOCALAPPDATA "dev-alchemy" }
$VagrantRoot = Join-Path $AppDataDir ".vagrant"
$env:VAGRANT_DOTFILE_PATH = Join-Path $VagrantRoot "linux-ubuntu-server-packer"
cd deployments\vagrant\linux-ubuntu-hyperv
vagrant destroy -f
vagrant box remove linux-ubuntu-server-packer --provider hyperv
$env:VAGRANT_DOTFILE_PATH = Join-Path $VagrantRoot "linux-ubuntu-desktop-packer"
vagrant box remove linux-ubuntu-desktop-packer --provider hyperv
cd ..\..\..