Vagrant with Macbook Mx (arm64)
Managing VMs with Vagrant + QEMU on arm64 Macbooks
For most local development workflows, Docker, is often the preferred tooling, but there sometimes are need to run a full virtual machine, ideally with popular tooling like Vagrant, which can manage virtual machines, connectivity, as well as provisioning the system with scripts or a tool like Ansible.
On new Macbooks M1/M2/M3, that comes with arm64
processor, this is not so straightforward. This article covers a few quick steps where you can use QEMU to run virtual machines with either arm64
virtual machines using Apple’s hypervisor, or use a emulator to run amd64
virtual machines.
Requirements
- Operating System: macOS 12.6.3 or higher
- Hardware: Apple M1 or newer generation
- Software: Homebrew for installing packages
Tools Installed
- QEMU 8.2.1
- Vagrant 2.4.1
- Vagrant
vagrant-qemu
plugin 0.3.5
Installation
The initial steps will be to get the virtual machine solution (QEMU) and install Vagrant with the QEMU plugin:
# install VM solution
brew install qemu
# install Vagrant with QEMU support
brew install --cask vagrant
vagrant plugin install vagrant-qemu
Configure and Launch arm64 image
Afterward, set up a Vagrant configuration file, download the VM image, start the virtual machine, and log into the VM.
# create configuration file for arm64 vm image
cat <<EOF > Vagrantfile
Vagrant.configure("2") do |config|
config.vm.box = "perk/ubuntu-2204-arm64"
end
EOF
# download and startup VM using hvf
vagrant up --provider=qemu
# log into the VM
vagrant ssh
This will use virtualization with the the native hypervisor built into the macOS.
Testing the virtual machine (arm64)
Once inside you can install inxi and neofetch:
sudo apt-get update
sudo apt install -y inxi neofetch
Then test with using neofetch
:
And test the environment by running with inxi
by typing:
inxi --system --machine -- cpu -- network --disk --info
You should see something like this:
Configure and Launch x86 image
The default settings for vagrant-qemu
plugin will not work for running Intel based images, so we’ll have to make some adjustments to the Vagrant configuration (Vagrantfile
).
Run this in a separate directory to keep configurations for amd64
and arm64
separated.
📓 NOTE: If you are using the same directory, you’ll need to run vagrant destroy
to clean up the previous virtual machine.
cat <<EOF > Vagrantfile
Vagrant.configure("2") do |config|
config.vm.box = "generic/ubuntu2204"
config.vm.provider "qemu" do |qe|
qe.arch = "x86_64"
qe.machine = "q35"
qe.cpu = "max"
qe.net_device = "virtio-net-pci"
qe.ssh_port = "50023"
end
end
EOF
# download and startup VM using q35 emulator
vagrant up --provider=qemu
# log into the VM
vagrant ssh
Here’s is a break down of some of the setting changes:
arch
: specifyx86_64
(intel) to run amd64 images.machine
: default isvirt,accel=hvf,highmem=on
, which uses built-in hypervisor on the macOS. Forx64_64
, we’ll need to use the emulator, so useq35
.cpu
: default ishome
, change this tomax
.- net_device: the default
virtio-net-device
will not work as there is novirtio-bus
with the emulator. Change this tovirtio-net-pci
. ssh_port
: the default is50022
, so we need to change to another port. Runlsof -nP -iTCP:50022
to see the if the port is in use.
Testing with the emulator (x86_64)
Once inside you can install inxi and neofetch:
sudo apt-get update
sudo apt install -y inxi neofetch
Then test with using neofetch
:
And test the environment by running with inxi
by typing:
inxi --system --machine -- cpu -- network --disk --info
You should see something like this:
Resources
Articles
These are articles that I have come across when researching this.
- ARM64 VM on macOS with libvirt + QEMU
- Vagrant QEMU on Apple Silicon
- ARM64 VM on macOS with libvirt + QEMU
Vagrant Boxen
Other
Conclusion
That’s all there is to this. The tool QEMU has been around for a long time, and supports a variety of emulators for different processors and supports native virtualization. On macOS, virtualization default is Hypervisor Framework (hvf), and on Linux, KVM is supported. The QEMU tool has always been common tool to manage both emulators and a variety of virtualization solutions.
For those not familiar with Vagrant, this is a tool that manages virtual machines through a single intuitive interface command-line interface and configuration file called Vagrantfile
. Vagrant also automates connections to the virtual machine, such as ssh, and provisioning the virtual machine using scripts, change configuration such as Ansible, or containers with tools like Docker.
The plugin for Vagrant vagrant-qemu
is a wrapper for the qemu
command line tool. With this, you can download images that support qemu
from https://app.vagrantup.com.