, , , ,

DevStack deployment

As we know basics about openstack, let’s experiment it’s simplest form devstack.

Install a virtualization program if not already present

Here I will install kvm to my debian host with informations given in debian wiki. I will install qemu-kvm for kernel module, and libvirt-bin for virtualization daemon and virtinst for command line guest creation.


Then add users of concern to kvm and libvirt groups


and install virt-manager for gui control. Adding guest OS will be trivial using virt-manager.


Kvm GUI virt-manager usage resembles similar to somewhat more popular VirtualBox / WmWare.  If virt-manager fails to start virtual machines due to default network error like;


Try starting network manually using;

virsh net-start


Here I created a template from scratch in order to enable custom modifications to support common bare minimums of the context. Another option may be downloading a template from one of already present alternatives.  As our template is ready, let’s work on vagrant. Vagrant will be used as configuration controller/provisioner that will help us do things in a reproducible and programmatic way. For now it may be seem like matrix in matrix to use openstack in vagrant but lets continue and see what it will look line at the end.  Preparing a vagrant base box for virtual box is handled before, and same principles may be applied here. After template is ready, try creating a base box with;


Here vagrant states it’s preference to VirtualBox. As we use KVM, this love story seems impossible unless we take necessary measures. In order to use KVM, we need to install a plug in vagrant-libvirt that adds a libvirt provider to vagrant. First install dependencies listed below (some of them should already be installed up to now);


Then install vagrant-libvirt plugin. Here I installed plug in as root but better install it at login that will be using vagrant.


In order to create a base box, we may follow box format specification. First create a temporary directory, copy guest image (that will normally be in /var/lib/libvirt/images/), create a json document (metadata.json) and a configuration file (Vagrantfile), and finally unite these into a single file using tar as presented below.


While copying it is better also rename image to box.img. Then create metadata and configuration files as;



And tar these into a .box file,


Now, we may create a base box (called debian86 here)  as;


Now, create a directory for the project, and in that directory, initialize a vagrant project with

vagrant init

Here, we will see a blank Vagrantfile for vagrant configuration. Change Vagrantfile to enable puppet for provisioning, and create necessary files accordingly. Two divergences from the link are,

  • set preferred hypervisor at the start of Vagrantfile, which will be libvirt,

This is optional, and you may also use –provider=’libvirt’ with corresponding vagrant commands, such as vagrant up / vagrant status.

  • And if not already done generate ssh keys with;

or remove corresponding entry in ssh key path in Vagrantfile configuration. It is better to create one if you intend to use your host keys in guest through key forwarding. Then configure vagrant files in order to;

  • clone devstack respository
  • create a basic configuration
  • create an appropriate user
  • and install openstack

After all, sample configuration for devstack will be;

Vagrantfile (./Vagrantfile)


# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|

# Template box
 config.vm.box = "debian86"

# Guest hostname and ip
 config.vm.hostname = "devstack"
 config.vm.network :private_network, ip: ""

# Guest hardware, 2048MB ram and 1 cpu
 config.vm.provider "libvirt" do |lv|
 lv.memory = 2048
 lv.cpus = 1

# Configure shared folders
 config.nfs.functional = false
 config.vm.synced_folder ".", "/vagrant", disabled: true
 config.vm.synced_folder "synced_folder", "/synced_folder", type: "rsync", create: true
 # Set puppet as provisioner and configure puppet modules path
 config.vm.provision :puppet do |puppet|
 puppet.module_path = "puppet/modules"
 puppet.manifests_path = "puppet/manifests"
 puppet.options = ['--verbose']

# Use ssh keys of host
 config.ssh.forward_agent = true
 config.ssh.private_key_path = ['~/.vagrant.d/insecure_private_key', '~/.ssh/id_rsa']


Puppet manifest (./puppet/manifests/default.pp)

# set path for executables
Exec { path => [ "/bin/", "/sbin/", "/usr/bin/", "/usr/sbin/" ] }

# list packages that should be installed
$system_packages = [ 'vim', 'g++', 'make', 'git', 'python', 'python-pip']

# perform an update
exec { 'update':
 command => 'apt-get update'

# install system packages after an update
package { $system_packages:
 ensure => "installed",
 require => Exec['update']

# create a user "stack"
user { 'stack':
 ensure => "present",
 home => "/home/stack",
 managehome => true,
 notify => Exec['update_sudoers']

# add user 'stack' in sudoers list
exec { 'update_sudoers':
 command => "/bin/echo \"stack ALL=(ALL) NOPASSWD: ALL\" >> /etc/sudoers",
 refreshonly => true,
 require => User['stack']

# clone devstack repository
exec{ 'clone_repository' :
 creates => '/home/stack/devstack',
 cwd => "/home/stack",
 command => "git clone -v https://git.openstack.org/openstack-dev/devstack",
 user => 'stack',
 provider => shell,
 require => [Exec['update_sudoers'], Package['git']]

# copy templete configuration file, 
# remember that "puppet:///modules/localconf/local.conf" will
# match to %vagrant_root%/modules/localconf/files/local.conf
file{ 'local_conf' :
 path => '/home/stack/devstack/local.conf',
 ensure => file,
 source => "puppet:///modules/localconf/local.conf",
 owner => 'stack',
 group => 'stack',
 mode => 0744,
 require => Exec['clone_repository'],
 notify => Exec['install_devstack']

# install devstack
exec{ 'install_devstack' :
 cwd => "/home/stack/devstack",
 command => "./stack.sh",
 user => 'stack',
 provider => shell,
 refreshonly => true,
 require => File['local_conf']

Puppet module (./puppet/modules/localconf/files/local.conf)


Then start the engine;

vagrant up

Here for my debian 8.6 host, and vagrant-lbvirt 0.0.36, I encountered a dhcp lease problem that made my guests unable to obtain ip;


There is an issue about this git repository of fog-libvirt. while waiting for permanent fix,

as a solution


may be modified as suggested;


And also beware that there is a bug about halted guests ending in suspended state in guests with gui. Temporary solution may be using guests own controls using virt manager console while waiting a fix.

After ./stack.sh is executed at puppet manifest, our guest should have keystone, glance, nova, cinder, neutron and horizon installed.


We may access openstack cli by;


Next step will be getting familiar with devstack