Use Vagrant, packer and puppet to automate the creation of development environments (Part 2)

This is the second part in a series of posts about Vagrant, Packer and Puppet and how you could use them to automate (and simplify) the creation and distribution of development environments. If you haven’t done that already go ahead and read the first part. We will be waiting for you to come back!

I made a few assumptions throughout this post. These are, you have some familiarity with VirtualBox, some familiarity using a linux distibution, and some comfort using the linux terminal. While these assumptions have been made, they are not mandatory in following this post.

In this post we will create a virtual machine in VirtualBox with Ubuntu Server 14.04 64bit as a guest OS. Then we will export it as a Vagrant box. Here is the configuration I will be using.

Host OS: Ubuntu 14.10 64bit
VirtualBox 4.3.18 (Although as of this writing the latest version is 4.3.20)
Vagrant 1.6.5
Packer 0.7.2

Before I continue, I should point out that you don’t have to create a virtual machine and then export to Vagrant box, as there are readily available for you to download, on a variety of OS and configurations from places like and There are however, a lot of reasons why you would want to do it by yourself. And of course, the learning process requires us to do it by ourselves!

First, we have to create the virtual machine in VirtualBox. I will not cover the process here, as there are numerous tutorials and how-tos out there. For reference, you can follow the instructions listed here. You would need to download the Ubuntu Server iso beforehand. Please use the following configuration when setting up your virtual machine.

Name: vagrand-<distribution><architecture>, so it should be vagrant-ubuntu64
Type: Linux
Version: Ubuntu 64
Memory Size: 1GB recommended
New Virtual Disk: Type: VMDK, Dynamically Allocated, Size: 40GB

Next, we should modify the VM’s settings for performance and to set up port forwarding for ssh.

Disable audio.
Disable usb
Make sure Network Adapter 1 is set to NAT
While you are in the Network Tab, in settings, click the Advanced arrow. Then click set Port Forwarding for the following.
Add this port forwarding rule:
Name: SSH
Protocol: TCP
Host IP:
Host Port: 2222
Guest IP:
Guest Port: 22

Then, you continue normally with the installation as described in the link I gave you before. It is just a matter of following screens and clicking next. When asked about setting up the user, password, hostname etc you can use whatever you like. For this example, I will use vagrant to everything just to keep it simple. Remember to remove the iso from the Virtual Machine’s settings after you are done, or else next time you boot it, the setup process will start again. If you haven’t done that, login to your Virtual Machine.

So, after the setup process finishes, update the installation. Run these two commands.

sudo apt-get update
sudo apt-get upgrade

If there are Kernel updates you might want to restart the VM. Now we need to set up the root user.

sudo passwd root

Now login in as the root user.

su -

Vagrant needs to be able to run sudo commands without a password prompt. While you are signed in as root, run the following command. It will add the vagrant user in the sudoers file. Anything in the /etc/sudoers.d/ is included in the sudoers privileges when created by the root user.

sudo visudo -f /etc/sudoers.d/vagrant

Now, we need to install the vagrant key. Vagrant needs ssh to communicate with the guest OS in the VM, that’s why it’s needed. Issue the following commands one at a time.

mkdir -p /home/vagrant/.ssh
chmod 0700 /home/vagrant/.ssh
wget --no-check-certificate -O /home/vagrant/.ssh/authorized_keys
chmod 0600 /home/vagrant/.ssh/authorized_keys
chown -R vagrant /home/vagrant/.ssh

Now you need to install and configure openSSH server if you didn’t do it during installation.

sudo apt-get install openssh-server

Next we edit the /etc/ssh/sshd_config file.

sudo vim /etc/ssh/sshd_config

We have to find and uncomment the following line, since we already added the vagrant key to the authorized_keys

AuthorizedKeysFile %h/.ssh/authorized_keys

Then we restart the ssh server

sudo service ssh restart

Next we will install the guest tools. We need to be able to compile to install guest tools so we install these first.

sudo apt-get install gcc build-essential linux-headers-server

This will take a couple of minutes to complete. When it does, go to VirtualBox (be sure to be looking at the server installation) and click on the Devices menu on the top. Click on Insert Guest Additions CD Image. You will most probably be prompted to download it. The guest tools will be in the form of an ISO that we need to mount it in our virtual CDROM. To do that we need to issue the following commands.

sudo mount /dev/cdrom /mnt 
cd /mnt
sudo ./

The above commands didn’t work for me right away, so I went to my VM’s settings, clicked on storage. I clicked the first + sign next to the Controller:IDE, and automatically mount the guest addition tools iso. It will be in your host OS, in /home/your_username/.config/VirtualBox/ folder. And then I run the commands again. You will get a warning about the cdrom being mounted as read-only which is fine.

We are now near the end. It’s time to package our box! First we “zero out” the drive. This will fix fragmentation issues and will allow it to compress even better. This will take some time. Also, if you didn’t give your VM enough disk space this might fail. When the commands complete, shutdown the VM.

sudo dd if=/dev/zero of=/EMPTY bs=1M
sudo rm -f /EMPTY
sudo shutdown -h now

And finally, we are ready to extract our VM to a Vagrant box! It’s best to create a directory where we will store it and enter that directory. We issue the following commands in our host OS, while in our home directory.

mkdir vagrant_boxes
cd vagrant_boxes

And finally the command that will make all that magic! This will cause vagrant to check VirtualBox for any VM with that name, and convert them to vagrant boxes. Remember that vagrant-ubuntu64 is the name of our Virtual Machine. This will take some time.

vagrant package --base vagrant-ubuntu64

Just for reference, this is the output.

sotos@sotos-box:~/vagrant_boxes$ vagrant package --base vagrant-ubuntu64
==> vagrant-ubuntu64: Exporting VM...
==> vagrant-ubuntu64: Compressing package to: /home/sotos/vagrant_boxes/

Now we simply add the newly created box to Vagrant, initialize it and boot it.

vagrant box add ubuntu64
vagrant init ubuntu64
vagrant up

Finally, to connect to your Vagrant box issue:

vagrant ssh

And now you have root access to your newly created vagrant box! Congratulations! While we can’t really do anything as it’s simply a base box, we really came a long way. You could start installing software to make a LAMP stack, but that would simply defeat the purpose of using Vagrant. So please don’t do it! You could alternatively use a provisioning script, where you could make sure certain software is installed and some configuration is done. While this could work on some occasions and if the project is small and simple, you will soon find out that this has its limitations. You could give it a try though. Finally, you could install a full blown provisioning tool like chef or puppet. This will give you much more freedom and options to do much more with your box. We will discuss about both the provisioning file and puppet in a later post in the series. In the next post of this series we will talk about using Packer to completely automate the process we did today.

To exit our box we type ‘exit’. That will bring us back to our host OS terminal. The Virtual Machine is still running though. To shut it down, we issue ‘vagrant halt’.

This second part of the series, was influenced (and based) from this post from Tyler Bird.