Swift Software Group

How to use Berkshelf, Chef Zero, Vagrant and VirtualBox

In this post we show how you can use Berkshelf, Chef Zero, Vagrant, and VirtualBox to provision Ubuntu 14.04 guest on Windows 10 host.

Before You Begin

You need VirtualBox and Vagrant installed. To do that, you can follow the steps described in Ubuntu with Vagrant and VirtualBox on Windows.

Install Vagrant-Omnibus Plugin

vagrant plugin install vagrant-omnibus

Install Vagrant-Berkshelf Plugin

vagrant plugin install vagrant-berkshelf

Install Chef Development Kit (ChefDK)

In PowerShell as Administrator:

choco install chefdk

Install Knife Solo

At this time we only need knife solo to generate an empty Chef repository that is compatible with Chef Zero. For more information see Knife Solo.

chef gem install knife-solo

Create Chef Repository

Create a chef-repo directory

mkdir ubuntu-chef-repo
cd ubuntu-chef-repo

Setup the the chef-repo directory

touch Berksfile
chef exec knife solo init . --no-git

Paste this into the Berksfile:

source 'https://supermarket.chef.io'

cookbook 'main', path: './site-cookbooks/main'

Create New Cookbook

cd site-cookbooks
chef exec berks cookbook main --skip-git --skip-test-kitchen --no-foodcritic --no-chef-minitest --no-bundler --skip-vagrant

Check the structure of the main cookbook:

tree /F main

It should have the following structure:

│   Berksfile
│   CHANGELOG.md
│   chefignore
│   LICENSE
│   metadata.rb
│   README.md
│   Thorfile
│
├───attributes
├───files
│   └───default
├───libraries
├───providers
├───recipes
│       default.rb
│
├───resources
└───templates
    └───default

Add the Apt Cookbook as a Dependency

The apt cookbook runs the apt-get update command on the guest system. See apt Cookbook - Chef Supermarket for details.

Open the site-cookbooks/main/metadata.rb file and add the following code at the end (the version may be different than 2.9.2):

depends 'apt', '~> 2.9.2'

This is how the final file should look like:

name             'main'
maintainer       'YOUR_NAME'
maintainer_email 'YOUR_EMAIL'
license          'All rights reserved'
description      'Installs/Configures main'
long_description 'Installs/Configures main'

version          '0.1.0'

depends 'apt', '~> 2.9.2'

Include the Apt Cookbook in the Default Recipe

Open site-cookbooks/main/recipes/default.rb and add the following code at the end:

include_recipe 'apt::default'

The final file looks like this:

#
# Cookbook Name:: main
# Recipe:: default
#
# Copyright (C) 2016 YOUR_NAME
#
# All rights reserved - Do Not Redistribute
#

include_recipe 'apt::default'

Test

This will generate Berksfile.lock

berks install

Create Vagrantfile

Go to the Chef Repo root (ubuntu-chef-repo).

touch Vagrantfile

Open Vagrantfile and replace its content with the following one:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|
  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://atlas.hashicorp.com/search.
  #
  config.vm.box = "ubuntu/trusty64"

  # Provider-specific configuration so you can fine-tune various
  # backing providers for Vagrant. These expose provider-specific options.
  #
  config.vm.provider "virtualbox" do |vb|
    # For a complete reference, please see the online documentation at
    # https://docs.vagrantup.com/v2/virtualbox/configuration.html

    # Name used in Oracle VM VirtualBox Manager GUI
    vb.name = "berkshelf-ubuntu-kitchen"

    # Customize the amount of memory on the VM (in MB):
    vb.memory = "2048"

    # Customize the amount of video memory on the VM (in MB):
    vb.customize ["modifyvm", :id, "--vram", "128"]
  end

  # Install the latest version of Chef.
  # For more information see https://github.com/chef/vagrant-omnibus
  #
  config.omnibus.chef_version = :latest

  # Enabling the Berkshelf plugin.
  config.berkshelf.enabled = true

  # Provision with Chef Zero
  #
  config.vm.provision :chef_zero do |chef|
    # Specify the local paths where Chef data is stored
    chef.cookbooks_path = [ 'cookbooks', 'site-cookbooks' ]
    chef.data_bags_path = "data_bags"
    chef.nodes_path = "nodes"
    chef.roles_path = "roles"

    # Add a recipe
    chef.add_recipe "main::default"
  end
end

Test

vagrant up
vagrant provision