diff --git a/.gitignore b/.gitignore
index 38dc873c2b..626fc7e936 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,3 +29,6 @@ dev/vagrant/vagrantkey
 dev/vagrant/vagrantkey.pub
 dev/vagrant/storage/
 .vagrant/
+
+# Files generated by JetBrains
+.idea/
diff --git a/dev/vagrant/Vagrantfile b/dev/vagrant/Vagrantfile
index ea7cc299a8..04393958bb 100644
--- a/dev/vagrant/Vagrantfile
+++ b/dev/vagrant/Vagrantfile
@@ -5,20 +5,38 @@ require "ipaddr"
 
 # Either libvirt or virtualbox
 PROVIDER = "libvirt"
+# Either centos or ubuntu
+DISTRO = "centos"
 
 PROVIDER_DEFAULTS = {
   libvirt: {
-    base_image: "centos/7",
-    bridge_interface: "virbr0",
-    vagrant_shared_folder: "/home/vagrant/sync",
-    sync_method: "nfs",
+    centos: {
+      base_image: "centos/7",
+      bridge_interface: "virbr0",
+      vagrant_shared_folder: "/home/vagrant/sync",
+      sync_method: "nfs",
+      provision_script: "bootstrap.sh",
+      kolla_path: "/home/vagrant/kolla"
+    }
   },
   virtualbox: {
-    base_image: "puppetlabs/centos-7.0-64-puppet",
-    bridge_interface: "wlp3s0b1",
-    vagrant_shared_folder: "/vagrant",
-    sync_method: "virtualbox",
-  },
+    centos: {
+      base_image: "puppetlabs/centos-7.0-64-puppet",
+      bridge_interface: "wlp3s0b1",
+      vagrant_shared_folder: "/vagrant",
+      sync_method: "virtualbox",
+      provision_script: "bootstrap.sh",
+      kolla_path: "/home/vagrant/kolla"
+    },
+    ubuntu: {
+      base_image: "ubuntu/vivid64",
+      bridge_interface: "wlp3s0b1",
+      vagrant_shared_folder: "/home/vagrant/sync",
+      sync_method: "nfs",
+      provision_script: "ubuntu-bootstrap.sh",
+      kolla_path: "/usr/local/kolla"
+    }
+  }
 }
 
 # Whether to do Multi-node or All-in-One deployment
@@ -30,6 +48,33 @@ NUMBER_OF_COMPUTE_NODES=1
 NUMBER_OF_STORAGE_NODES=1
 NUMBER_OF_NETWORK_NODES=1
 
+NODE_SETTINGS = {
+  aio: {
+    cpus: 4,
+    memory: 4096
+  },
+  operator: {
+    cpus: 1,
+    memory: 1024
+  },
+  controller: {
+    cpus: 1,
+    memory: 2048
+  },
+  compute: {
+    cpus: 1,
+    memory: 1024
+  },
+  storage: {
+    cpus: 1,
+    memory: 1024
+  },
+  network: {
+    cpus: 1,
+    memory: 1024
+  }
+}
+
 # Configure a new SSH key and config so the operator is able to connect with
 # the other cluster nodes.
 unless File.file?("./vagrantkey")
@@ -37,7 +82,11 @@ unless File.file?("./vagrantkey")
 end
 
 def get_default(setting)
-  PROVIDER_DEFAULTS[PROVIDER.to_sym][setting]
+  PROVIDER_DEFAULTS[PROVIDER.to_sym][DISTRO.to_sym][setting]
+end
+
+def get_setting(node, setting)
+  NODE_SETTINGS[node][setting]
 end
 
 Vagrant.configure(2) do |config|
@@ -76,7 +125,8 @@ Vagrant.configure(2) do |config|
       if vm.name
         `virsh -c qemu:///system net-dhcp-leases vagrant-private-dhcp | awk -F'[ /]+' '/#{vm.name} / {print $6}'`.chop
       end
-    when "virtualbox"
+    when "virtualbox_ubuntu"
+    when "virtualbox_centos"
       if vm.id
         `VBoxManage guestproperty get #{vm.id} "/VirtualBox/GuestInfo/Net/1/V4/IP"`.split()[1]
       end
@@ -86,13 +136,15 @@ 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 #{MULTINODE ? 'multinode' : 'aio'}"
-    admin.vm.synced_folder "../..", "/home/vagrant/kolla", create:"True", type: get_default(:sync_method)
+    admin.vm.provision :shell, path: get_default(:provision_script), args: "operator #{MULTINODE ? 'multinode' : 'aio'}"
+    admin.vm.synced_folder "../../etc/kolla", "/etc/kolla", type: "nfs"
+    admin.vm.synced_folder "../..", get_default(:kolla_path), create:"True", type: get_default(:sync_method)
     admin.vm.synced_folder "storage/operator/", "/data/host", create:"True", type: get_default(:sync_method)
     admin.vm.synced_folder "storage/shared/", "/data/shared", create:"True", type: get_default(:sync_method)
     admin.vm.synced_folder ".", get_default(:vagrant_shared_folder), disabled: true
     admin.vm.provider PROVIDER do |vm|
-      vm.memory = MULTINODE ? 1024 : 4096
+      vm.memory = MULTINODE ? get_setting(:operator, :memory) : get_setting(:aio, :memory)
+      vm.cpus = MULTINODE ? get_setting(:operator, :cpus) : get_setting(:aio, :cpus)
     end
     admin.hostmanager.aliases = "operator"
   end
@@ -107,7 +159,8 @@ Vagrant.configure(2) do |config|
         compute.vm.synced_folder "storage/shared/", "/data/shared", create:"True", type: get_default(:sync_method)
         compute.vm.synced_folder ".", get_default(:vagrant_shared_folder), disabled: true
         compute.vm.provider PROVIDER do |vm|
-          vm.memory = 1024
+          vm.memory = get_setting(:compute, :memory)
+          vm.cpus = get_setting(:compute, :cpus)
         end
         compute.hostmanager.aliases = "compute0#{i}"
       end
@@ -122,7 +175,8 @@ Vagrant.configure(2) do |config|
         storage.vm.synced_folder "storage/shared/", "/data/shared", create:"True", type: get_default(:sync_method)
         storage.vm.synced_folder ".", get_default(:vagrant_shared_folder), disabled: true
         storage.vm.provider PROVIDER do |vm|
-          vm.memory = 1024
+          vm.memory = get_setting(:storage, :memory)
+          vm.cpus = get_setting(:storage, :cpus)
         end
         storage.hostmanager.aliases = "storage0#{i}"
       end
@@ -137,7 +191,8 @@ Vagrant.configure(2) do |config|
         network.vm.synced_folder "storage/shared/", "/data/shared", create:"True", type: get_default(:sync_method)
         network.vm.synced_folder ".", get_default(:vagrant_shared_folder), disabled: true
         network.vm.provider PROVIDER do |vm|
-          vm.memory = 1024
+          vm.memory = get_setting(:network, :memory)
+          vm.cpus = get_setting(:network, :cpus)
         end
         network.hostmanager.aliases = "network0#{i}"
       end
@@ -152,7 +207,8 @@ Vagrant.configure(2) do |config|
         control.vm.synced_folder "storage/shared/", "/data/shared", create:"True", type: get_default(:sync_method)
         control.vm.synced_folder ".", get_default(:vagrant_shared_folder), disabled: true
         control.vm.provider PROVIDER do |vm|
-          vm.memory = 2048
+          vm.memory = get_setting(:controller, :memory)
+          vm.cpus = get_setting(:controller, :cpus)
         end
         control.hostmanager.aliases = "control0#{i}"
       end
diff --git a/dev/vagrant/ubuntu-bootstrap.sh b/dev/vagrant/ubuntu-bootstrap.sh
new file mode 100644
index 0000000000..aed1b766b9
--- /dev/null
+++ b/dev/vagrant/ubuntu-bootstrap.sh
@@ -0,0 +1,82 @@
+#!/bin/bash
+
+registry=operator.local
+registry_port=4000
+
+install_ansible() {
+    echo "Installing Ansible"
+    apt-get install -y software-properties-common
+    apt-add-repository -y ppa:ansible/ansible
+    apt-get update
+    apt-get install -y ansible=1.9.4*
+    cat >/root/.ansible.cfg <<-EOF
+[defaults]
+forks=100
+
+[ssh_connection]
+scp_if_ssh=True
+EOF
+}
+
+install_docker() {
+    echo "Installing Docker"
+    apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D
+    echo "deb https://apt.dockerproject.org/repo ubuntu-trusty main" > /etc/apt/sources.list.d/docker.list
+    apt-get update
+    apt-get install -y  docker-engine=1.8.2*
+    sed -i -r "s,^[# ]*DOCKER_OPTS=.+$,DOCKER_OPTS=\"--insecure-registry $registry:$registry_port\"," /etc/default/docker
+}
+
+install_python_deps() {
+    echo "Installing Python"
+    # Python
+    apt-get install -y python-setuptools python-dev libffi-dev libssl-dev
+    easy_install pip
+    pip install --upgrade pip virtualenv virtualenvwrapper
+}
+
+install_ntp() {
+    echo "Installing NTP"
+    # NTP
+    apt-get install -y ntp
+}
+
+create_registry() {
+    echo "Creating Docker Registry"
+    docker run -d \
+            --name registry \
+            --restart=always \
+            -p 4000:5000 \
+            -e STANDALONE=True \
+            -e MIRROR_SOURCE=https://registry-1.docker.io \
+            -e MIRROR_SOURCE_INDEX=https://index.docker.io \
+            -e STORAGE_PATH=/var/lib/registry \
+            -v /data/host/registry-storage:/var/lib/registry \
+            registry
+}
+
+configure_kolla() {
+    echo "Configuring Kolla"
+    pip install -r /home/vagrant/kolla/requirements.txt
+}
+
+echo "Kernel version $(uname -r)"
+if [[ $(uname -r) != *"3.19"* ]]; then
+    echo "Going to update kernel image"
+    apt-get update
+    apt-get install -y linux-image-generic-lts-vivid
+    # VM needs to be rebooted for docker to pickup the changes
+    echo "Rebooting for kernel changes"
+    echo "After reboot re-run vagrant provision to finish provising the box"
+    reboot
+    # Sleep for a bit to let vagrant exit properly
+    sleep 3
+fi
+
+install_ansible
+install_docker
+install_ntp
+install_python_deps
+create_registry
+configure_kolla
+