Run a Full OpenStack Cloud on Your compute

Run a Full OpenStack Cloud on Your Mac — No Dedicated Server Required

For years, “trying OpenStack” meant either renting servers or fighting an all-in-one VM that barely fit on a laptop. I wanted something different: a realistic, production-like cloud lab running entirely on an Apple Silicon Mac — same APIs, same workflows, same Terraform code I’d use in production.

The result is now open source: openstack-dev-platform.


🎯 What you get

A complete OpenStack environment running inside a single Multipass ARM64 VM on your Mac:

  • OpenStack 2026.1 deployed via Devstack
  • OVN software-defined networking with real floating IPs on your local network
  • Octavia load balancer (OVN driver — no Amphora VMs needed)
  • Skyline, the modern Vue.js dashboard (alongside Horizon)
  • Infrastructure-as-Code with two Terraform workloads (network + instances)
  • CentOS 9 Stream VMs accessible via SSH and the Cockpit web console
  • Every ARM64-specific quirk documented and fixed
  • ✅ Multi-tenancy patterns — from isolated projects to a full reseller portal architecture

🧩 The stack

Layer Tool
Hypervisor Multipass (Canonical, ARM64-native)
OS Ubuntu 24.04
OpenStack deployment Devstack stable/2026.1
SDN OVN (Open Virtual Network)
Load balancing Octavia with OVN driver
Provisioning Terraform (terraform-provider-openstack ~> 2.0)
Guest OS CentOS 9 Stream (ARM64 cloud image)

The lab runs on a Mac Studio M1 Pro with 4 vCPU / 12 GB RAM / 200 GB disk allocated to the VM.


🧠 The ARM64 part nobody warns you about

The trickiest part wasn’t OpenStack itself — it was getting it to behave on Apple Silicon. The repository documents each fix in detail, but here’s the short list:

  • Nova CPU model — the default cortex-a15 is 32-bit and triggers No PCI buses available on every VM boot. Switch to cortex-a57.
  • OVN agent Python path — the agent uses the system Python and fails with ModuleNotFoundError: neutron. Patch $PYTHON to the venv path.
  • br-ex bridge — Devstack won’t attach an interface it doesn’t own. Dedicate enp0s2 to OVS, leave enp0s1 for management, and make the attachment permanent with a systemd service.
  • Cloud-init metadata — the OVN metadata proxy drops the X-Instance-ID header, so cloud images never get their SSH keys. Solution: config_drive = true in Terraform.
  • Image properties — without hw_machine_type=virt, hw_firmware_type=uefi, and hw_disk_bus=virtio, ARM64 guests boot into nothing.

Each fix is one line. Finding them took days.


🚀 Why I built it

I wanted a sandbox where I could:

  • Learn OpenStack internals by actually breaking and fixing things
  • Test Terraform modules against the real OpenStack provider before pushing to production
  • Validate cloud-init configurations end-to-end
  • Experiment with Neutron + OVN networking without a homelab full of switches
  • Understand how private clouds work before touching one in production

Everything you’d typically need a rack of servers for — running quietly on a Mac.


🔗 Repository

👉 github.com/colussim/openstack-dev-platform

The README is a full step-by-step guide: Multipass setup, Devstack local.conf, OVN configuration, image upload, both Terraform workloads, and every ARM64 fix.