diff --git a/vagrant/Vagrantfile b/vagrant/Vagrantfile
index d285099a4c1df33f48d1187288093ae0dfa450bf..f22e0c0b0adc8bc107ce9d65b63ba9707dde972e 100644
--- a/vagrant/Vagrantfile
+++ b/vagrant/Vagrantfile
@@ -1,6 +1,9 @@
 # -*- mode: ruby -*-
 # vi: set ft=ruby :
 
+# Whether to do Multi-node or All-in-One deployment
+MULTINODE=true
+
 # Configure a new SSH key and config so the operator is able to connect with
 # the other cluster nodes.
 if not File.file?("./vagrantkey")
@@ -47,80 +50,82 @@ Vagrant.configure(2) do |config|
   # The operator controls the deployment
   config.vm.define "operator" do |admin|
     admin.vm.hostname = "operator.local"
-    admin.vm.provision :shell, path: "bootstrap.sh", args: "operator"
+    admin.vm.provision :shell, path: "bootstrap.sh", args: "operator #{MULTINODE ? 'multinode' : 'aio'}"
     admin.vm.synced_folder "storage/operator/", "/data/host", create:"True"
     admin.vm.synced_folder "storage/shared/", "/data/shared", create:"True"
     admin.vm.synced_folder ".", "/vagrant", disabled: true
     admin.vm.provider "virtualbox" do |vb|
-      vb.memory = 1024
+      vb.memory = MULTINODE ? 1024 : 4096
     end
     admin.hostmanager.aliases = "operator"
   end
 
-  # Build compute nodes
-  (1..1).each do |i|
-    config.vm.define "compute0#{i}" do |compute|
-      compute.vm.hostname = "compute0#{i}.local"
-      compute.vm.provision :shell, path: "bootstrap.sh"
-      compute.vm.synced_folder "storage/compute/", "/data/host", create:"True"
-      compute.vm.synced_folder "storage/shared/", "/data/shared", create:"True"
-      compute.vm.synced_folder ".", "/vagrant", disabled: true
-      compute.vm.provider "virtualbox" do |vb|
-        vb.memory = 1024
+  if MULTINODE
+    # Build compute nodes
+    (1..1).each do |i|
+      config.vm.define "compute0#{i}" do |compute|
+        compute.vm.hostname = "compute0#{i}.local"
+        compute.vm.provision :shell, path: "bootstrap.sh"
+        compute.vm.synced_folder "storage/compute/", "/data/host", create:"True"
+        compute.vm.synced_folder "storage/shared/", "/data/shared", create:"True"
+        compute.vm.synced_folder ".", "/vagrant", disabled: true
+        compute.vm.provider "virtualbox" do |vb|
+          vb.memory = 1024
+        end
+        compute.hostmanager.aliases = "compute0#{i}"
       end
-      compute.hostmanager.aliases = "compute0#{i}"
     end
-  end
 
-  # Build storage nodes
-  (1..1).each do |i|
-    config.vm.define "storage0#{i}" do |storage|
-      storage.vm.hostname = "storage0#{i}.local"
-      storage.vm.provision :shell, path: "bootstrap.sh"
-      storage.vm.synced_folder "storage/storage/", "/data/host", create:"True"
-      storage.vm.synced_folder "storage/shared/", "/data/shared", create:"True"
-      storage.vm.synced_folder ".", "/vagrant", disabled: true
-      storage.vm.provider "virtualbox" do |vb|
-        vb.memory = 1024
+    # Build storage nodes
+    (1..1).each do |i|
+      config.vm.define "storage0#{i}" do |storage|
+        storage.vm.hostname = "storage0#{i}.local"
+        storage.vm.provision :shell, path: "bootstrap.sh"
+        storage.vm.synced_folder "storage/storage/", "/data/host", create:"True"
+        storage.vm.synced_folder "storage/shared/", "/data/shared", create:"True"
+        storage.vm.synced_folder ".", "/vagrant", disabled: true
+        storage.vm.provider "virtualbox" do |vb|
+          vb.memory = 1024
+        end
+        storage.hostmanager.aliases = "storage0#{i}"
       end
-      storage.hostmanager.aliases = "storage0#{i}"
     end
-  end
 
-  # Build network nodes
-  (1..1).each do |i|
-    config.vm.define "network0#{i}" do |network|
-      network.vm.hostname = "network0#{i}.local"
-      network.vm.provision :shell, path: "bootstrap.sh"
-      network.vm.synced_folder "storage/network/", "/data/host", create:"True"
-      network.vm.synced_folder "storage/shared/", "/data/shared", create:"True"
-      network.vm.synced_folder ".", "/vagrant", disabled: true
-      network.vm.provider "virtualbox" do |vb|
-        vb.memory = 1024
+    # Build network nodes
+    (1..1).each do |i|
+      config.vm.define "network0#{i}" do |network|
+        network.vm.hostname = "network0#{i}.local"
+        network.vm.provision :shell, path: "bootstrap.sh"
+        network.vm.synced_folder "storage/network/", "/data/host", create:"True"
+        network.vm.synced_folder "storage/shared/", "/data/shared", create:"True"
+        network.vm.synced_folder ".", "/vagrant", disabled: true
+        network.vm.provider "virtualbox" do |vb|
+          vb.memory = 1024
+        end
+        network.hostmanager.aliases = "network0#{i}"
       end
-      network.hostmanager.aliases = "network0#{i}"
     end
-  end
 
-  # Build control nodes
-  (1..3).each do |i|
-    config.vm.define "control0#{i}" do |control|
-      control.vm.hostname = "control0#{i}.local"
-      control.vm.provision :shell, path: "bootstrap.sh"
-      control.vm.synced_folder "storage/control/", "/data/host", create:"True"
-      control.vm.synced_folder "storage/shared/", "/data/shared", create:"True"
-      control.vm.synced_folder ".", "/vagrant", disabled: true
-      control.vm.provider "virtualbox" do |vb|
-        vb.memory = 2048
-      end
-      control.hostmanager.aliases = "control0#{i}"
+    # Build control nodes
+    (1..3).each do |i|
+      config.vm.define "control0#{i}" do |control|
+        control.vm.hostname = "control0#{i}.local"
+        control.vm.provision :shell, path: "bootstrap.sh"
+        control.vm.synced_folder "storage/control/", "/data/host", create:"True"
+        control.vm.synced_folder "storage/shared/", "/data/shared", create:"True"
+        control.vm.synced_folder ".", "/vagrant", disabled: true
+        control.vm.provider "virtualbox" do |vb|
+          vb.memory = 2048
+        end
+        control.hostmanager.aliases = "control0#{i}"
 
-      # TODO: Here we bind local port 8080 to Horizon on control01 only.
-      # TODO: Once we implement Horizon behind a VIP, this obviously needs to
-      # be changed.
-      #if i < 2 then
-      #  config.vm.network "forwarded_port", guest: 80, host: 8080
-      #end
+        # TODO: Here we bind local port 8080 to Horizon on control01 only.
+        # TODO: Once we implement Horizon behind a VIP, this obviously needs to
+        # be changed.
+        #if i < 2 then
+        #  config.vm.network "forwarded_port", guest: 80, host: 8080
+        #end
+      end
     end
   end
 
diff --git a/vagrant/bootstrap.sh b/vagrant/bootstrap.sh
index c6cdd9efb1375317552f11b603f5a9b0558f999e..17dd570591a6761c83df3e5df44e521c045a4691 100644
--- a/vagrant/bootstrap.sh
+++ b/vagrant/bootstrap.sh
@@ -6,8 +6,18 @@
 export http_proxy=
 export https_proxy=
 
+if [ $2 = 'aio' ]; then
+    # Run registry on port 4000 since it may collide with keystone when doing AIO
+    REGISTRY_PORT=4000
+    SUPPORT_NODE=operator
+else
+    REGISTRY_PORT=5000
+    SUPPORT_NODE=support01
+fi
+REGISTRY=operator.local:${REGISTRY_PORT}
+
 # Install common packages and do some prepwork.
-function prepwork {
+function prep_work {
     systemctl stop firewalld
     systemctl disable firewalld
 
@@ -21,7 +31,7 @@ function prepwork {
 }
 
 # Install and configure a quick&dirty docker daemon.
-function installdocker {
+function install_docker {
     # Allow for an externally supplied docker binary.
     if [ -f "/data/docker" ]; then
         cp /vagrant/docker /usr/bin/docker
@@ -41,7 +51,7 @@ EOF
 
         # Despite it shipping with /etc/sysconfig/docker, Docker is not configured to
         # load it from it's service file.
-        sed -i -r 's,(ExecStart)=(.+),\1=/usr/bin/docker -d --insecure-registry operator.local:5000 --registry-mirror=http://operator.local:5000,' /usr/lib/systemd/system/docker.service
+        sed -i -r "s,(ExecStart)=(.+),\1=/usr/bin/docker -d --insecure-registry ${REGISTRY} --registry-mirror=http://${REGISTRY}," /usr/lib/systemd/system/docker.service
 
         systemctl daemon-reload
         systemctl enable docker
@@ -52,7 +62,7 @@ EOF
 }
 
 # Configure the operator node and install some additional packages.
-function configureoperator {
+function configure_operator {
     yum install -y git mariadb && yum clean all
     pip install --upgrade ansible python-openstackclient
 
@@ -81,7 +91,7 @@ EOF
 
     # The openrc file.
     cat > ~vagrant/openrc <<EOF
-export OS_AUTH_URL="http://support01.local:35357/v2.0"
+export OS_AUTH_URL="http://${SUPPORT_NODE}:35357/v2.0"
 export OS_USERNAME=admin
 export OS_PASSWORD=password
 export OS_TENANT_NAME=admin
@@ -92,8 +102,8 @@ EOF
     # namespace.
     cat > ~vagrant/tag-and-push.sh <<EOF
 for image in \$(docker images|awk '/^kollaglue/ {print \$1}'); do
-    docker tag \$image operator.local:5000/lokolla/\${image#kollaglue/}:latest
-    docker push operator.local:5000/lokolla/\${image#kollaglue/}:latest
+    docker tag \$image ${REGISTRY}/lokolla/\${image#kollaglue/}:latest
+    docker push ${REGISTRY}/lokolla/\${image#kollaglue/}:latest
 done
 EOF
     chmod +x ~vagrant/tag-and-push.sh
@@ -106,7 +116,7 @@ EOF
         docker run -d \
             --name registry \
             --restart=always \
-            -p 5000:5000 \
+            -p $REGISTRY_PORT:5000 \
             -e STANDALONE=True \
             -e MIRROR_SOURCE=https://registry-1.docker.io \
             -e MIRROR_SOURCE_INDEX=https://index.docker.io \
@@ -116,9 +126,9 @@ EOF
     fi
 }
 
-prepwork
-installdocker
+prep_work
+install_docker
 
 if [ "$1" = "operator" ]; then
-    configureoperator
+    configure_operator
 fi