Wednesday 11 July 2012

Virtual Machines using Vagrant and Chef

Vagrant
VirtualBox
Chef

Vagrant + VirtualBox + Chef

With the use of Vagrant and Chef we can fully automate our Virtual Server deployment. Using Vagrant we can setup our VM by using a "base box" and using Chef "recipes" and "cookbooks" we can set what gets installed on the VM as it starts up so your virtual environment is already setup for use.

Some links that will be helpful:
for Chef
Opscode Documentation
Opscode Wiki
Opscode-Cookbooks *git You will need Virtual Box before we start anything else so download and install it:
Download Vagrant and install according to your machine and download Chef and install as well.

Setting up Vagrant

After you install Vagrant it will add the `vagrant` command to your terminal/command prompt. Type `vagrant -h` to get a list of all the commands associated with it, also read the documentation on the website as it's very thorough and precise.
To set up your Debian box follow these commands:
mkdir vagrantDeb cd vagrantDeb vagrant box add localDebian http://dl.dropbox.com/u/937870/VMs/squeeze64.box vagrant init localDebian
Your VM is now ready to build, but first we must configure our vagrantfile. Edit the vagrant file in the directory you made using the editor of your choice and make these changes:
  • Uncomment the line stating `config.vm.network :hostonly, "192.168.33.10"`. The IP address is arbitrary, just make sure it doesn't clash with other VM's.
  • Add:
    config.vm.customize do |vm|
            vm.memory_size = 512
        end
    

    This will set the RAM size, you can still change this in the virtualbox settings later so it doesn't matter too much.
  • Change share folder to: config.vm.share_folder "htdoc", "/var/www", "/htdoc". You can add more folders if you want, the syntax is `config.vm.share_folder "name", "guest/dir", "host/dir"
Now you are ready to run your VM. Enter the command `vagrant up` and your VM will boot. You must ssh into it so if you are using windows you will need to download a ssh program such as PuTTY. Use the IP 127.0.0.1 and port 2222.

Configuring VM

Now that your VM is setup we need to update it. Run `sudo apt-get update` and `sudo apt-get upgrade` to get everything up to date. Remember we won't be downloading any applications or tools manually, chef will be doing that for us.
You may have noticed after your `vagrant up` command that vagrant complained the VirtualBox guest additions were not the same version as your VirtualBox program. Comments on this report varying problems from not working at all to nothing happening, if you receive any problems here are the commands to update:
NOTE: VBoxGuestAdditions_4.X.Y relates to the version of Virtual Box you have.
wget -c http://download.virtualbox.org/virtualbox/4.0.8/VBoxGuestAdditions_4.X.Y.iso -O VBoxGuestAdditions_4.X.Y.iso sudo apt-get install build-essential module-assistant sudo m-a prepare sudo mount VBoxGuestAdditions_4.X.Y.iso -o loop /mnt sudo sh /mnt/VBoxLinuxAdditions.run --nox11 sudo /etc/init.d/vboxadd setup rm *.iso
That should be it for the guest additions. Now we need to upgrade our chef application on the VM with the following command:
sudo gem install chef --no-ri --no-doc
It's important to note that the version on your host and guest machine should be matching, so if you ever upgrade on make sure to upgrade the other.
Ta-da! Our VM is on like Donkey Kong!

Cooking up some Recipes

Chef is a configuration management tool that is written in Ruby. They come in recipes and recipes are grouped into cookbooks. There are many chef recipes and cookbooks already available online and we can write our own if we want. We include these recipes in our vagrant file so when we load our VM it will read these recipes and install the according applications and tools. First we create a directory for our recipes within our directory which contains our vagrantfile and then we will download the ones we need. If you are using Windows download the Git Bash tool:
mkdir cookbooks
cd cookbooks
git clone git://github.com/opscode-cookbooks/apache2.git
git clone git://github.com/opscode-cookbooks/apt.git
git clone git://github.com/opscode-cookbooks/build-essential.git
git clone git://github.com/opscode-cookbooks/git.git
git clone git://github.com/opscode-cookbooks/vim.git
git clone git://github.com/opscode-cookbooks/php.git
git clone git://github.com/opscode-cookbooks/mysql.git
git clone git://github.com/homemade/chef-dotdeb.git
The opscode-cookbooks page has a list of common application recipes that were made by opscode themselves. The last one is to upgrade php to 5.3 as the default Debian repo only has 5.3 (at time of writing!).
Now open up your vagrantfile and lets add these recipes. At line 70 or so in your vagrantfile it should start mentioning chef and all these commands will be commented out. Uncomment the ones you need and add your recipes as such:
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = "cookbooks"
chef.provisioning_path = "/tmp/vagrant-chef"
# chef.roles_path = "../my-recipes/roles"
# chef.data_bags_path = "../my-recipes/data_bags"
chef.add_recipe ("dotdeb")
chef.add_recipe ("dotdeb::php54")
chef.add_recipe ("apt")
chef.add_recipe ("apache2")
chef.add_recipe ("apache2::mod_php5")
chef.add_recipe ("apache2::mod_rewrite")
chef.add_recipe ("php")
chef.add_recipe ("build-essential")
chef.add_recipe ("git")
chef.add_recipe ("vim")

# # You may also specify custom JSON attributes:
# chef.json = { :mysql_password => "foo" }
end
Now we are ready to rebuild our VM. First lets go through some vagrant commands:
 vagrant up  start VM, whether new or halted
 vagrant halt  halts and stops VM, what you should be doing to shut it down
 vagrant reload  rebuilds the VM if changes have been made to the vagrantfile while it has been running
 vagrant destroy  deletes VM, but not the vagrant file. Don't do this unless absolutely necessary
Now just run  vagrant reload   and it will apply your changes made in the vagrantfile. Wait until the loading finishes and you VM is complete. If you wish to create multiple VM's for testing new configurations just make a new directory and use the command  vagrant init localDebian  . This will create a new vagrant file and a new vm, then just run  vagrant up   in this directory. Vagrant can do this as localDebian is saved in a .box format that vagrant uses. It builds your VM on top of this "base box" so you can build multiple VM's of the same box without effecting the other ones.