Configure a Apache VirtualHost with a chef cookbook

Step 3: Create a VHost with the Apache2 Cookbook

You can find the files for this step of the workshop in the following github repository:


Maintain dependencies in metadata.rb

You can find a lot of common cookbooks on the web and in the chef supermaket ( to provision a lot of services in a flexible way. You should use them because you need to implement less by your self.


In this step we will use the apache2 cookbook and have a look how we can integrate it with berkshelf to download and resolve dependencies.

The first step is, that you need to defined the dependencies in your "metadata.rb" file:

name 'mycookbook'
description 'Demo cookbook to create a virtual host for a webapp'
maintainer 'Timo Schmidt'
license 'none'
version '0.0.1'

depends 'apache2', '= 3.0.0'
depends 'hostsfile', '= 2.4.5‘

In the previous Example we defined that we define the "apache2" and "hostsfile" cookbook in a fixed version.


Including a dependency in a fixed version has the advantage that your cookbook will stell work, when there are breaking changes in the depending cookbook and you can race your dependecy, when you have tested your cookbook with the newer version.


Use Berkshelf to resolve dependencies

To be able to use Berkshelf, the first step would be to install the Vagrant Berkshelf plugin:

vagrant plugin install vagrant-berkshelf

When the vagrant plugin is ready we can add add file with the name "Berksfile" on the top level beside the "Vagrantfile".

We fill our Berksfile with the following content:

source ""

cookbook 'mycookbook', path: './site-cookbooks/mycookbook‘

Implement the cookbook to create the apache virtual host

During the proviosioning berkshelf will resolve the dependencies on the cookbooks "apache" and "hostsfile" and download them, that they are available in the provisioning process.

Now we need to implement the recipe. The recipe will create the folder structure, a dummy site and the apache configuration with the domain "".

# add hosts entry
hostsfile_entry '' do
   hostname  ''
   action    :create

# create directory
directory '/var/www/shop' do
   owner 'www-data'
   group 'vagrant'
   mode '0775'
   recursive true
   action :create

# create virtual host
web_app 'shop' do
   server_name ''
   server_aliases ['']
   docroot '/var/www/shop'
   cookbook 'apache2'

# create dummy content
execute "create dummy site" do
   command "echo 'hello' > /var/www/shop/index.html"
   cwd "/var/www/shop"
   action :run

# fix owner
execute "chown-data-www" do
   command "chown -R www-data:www-data ."
   cwd "/var/www/shop"
   action :run

# fix permission
execute "chmod-data-www" do
   command "chmod -R 775 ."
   cwd "/var/www/shop"
   action :run

As usual you can start the box with "vagrant up" and it will be available after a few minutes.

Create a local DNS entry in /etc/hosts and open the dummy site

Now you need to create a hosts entry in your local host system to resolve the name of your apache virtual host.

You can find it:

  • For MAC OS & Linux: /etc/hosts
  • For Windows: C:\Windows\System32\drivers\etc\hosts


And need to add the following line:

When you open "" in your browser now, your will see a dummy site, that was created with the recipe:


The Berksfile.lock

Maybe you have recognized that a file Berksfile.lock exists beside the normal Berksfile? It has the following content:

    path: site-cookbooks/mycookbook

  apache2 (3.0.0)
    iptables (>= 0.0.0)
    logrotate (>= 0.0.0)
  hostsfile (2.4.5)
  iptables (1.1.0)
  logrotate (1.9.2)
  mycookbook (0.0.1)
    apache2 (= 3.0.0)
    hostsfile (= 2.4.5)

This file contains the finger print of the cookbook dependencies at the time, the box was provisioned. As you might remember, the dependencies in "metadata.rb" could be defined with wildcards to e.g.: point to the latest relase.

The drawback is, your cookbook would break when there is a breaking change in the depending cookbbok. But if you now commit the Berksfile.lock, the dependecies from this file will be taken instead from Berksfile.


This can be used to implement a "continous integration process". The process would be "Checkout cookbook, delete Berksfile.lock => Vagrant up => Test if box still works with latest dependencies => commit Berksfile.lock". To use it like this, the depedencies need to point to the latest version for sure.

Now you know how to write one cookbooks and how to include external cookbooks. When you use more and more resources with vagrant and chef, the provisioning is getting slower. To prevent this, i've summarized some experiences to improve the performance of a vagrant setup.