Chef and Vagrant sitting in a tree
Chef and Vagrant - Getting started
These are tech notes from a hack session I had on the use of Chef solo.
Prerequisites
- Ruby
- Vagrant
- Bundler
Get started
Make a Gemfile
like so:
source 'https://rubygems.org'
gem 'knife-solo'
gem 'berkshelf'
Install the required gems with Bundler
bundle install
Start a Chef Solo project
Use knife to initialise the project, which creates some of the directories and files you will need.
knife solo init .
We’re using Berkshelf to access community cookbooks, so lets make the Berksfile
as we want
source 'https://supermarket.chef.io'
metadata
cookbook 'nginx'
We’ll be making custom recipies, so lets create our own cookbook
knife cookbook create workplace --cookbook-path=site-cookbooks
We should create a metadata.rb
in the root to tell Chef about our project
name 'chef-hack'
maintainer 'Workplace Systems ltd.'
maintainer_email 'info@workplacesystems.com'
license 'All rights reserved'
description 'Installs/Configures workplace applications'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
version '0.0.1'
depends 'nginx'
Prepare a machine
We need a Linux machine to provision. For this we have number of options
- spin up a box in “the cloud”
- install and network a phyical machine
- configure a virtual machine (vagrant)
Vagrant
Vagrant is nice tool to setup virtual machines locally, so lets use it. First off lets grab an image, Ubuntu will do.
vagrant box add trusty64 https://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box
vagrant init trusty64
Create some JSON to tell Chef about our box nodes/192.168.33.10.json
{
"run_list": [
"nginx",
"workplace"
]
}
When we ran vagrant init
a Vagrantfile
was created, lets customise that file so Vagrant brings the machine up as we want.
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
config.vm.box = "trusty64"
config.vm.network "private_network", ip: "192.168.33.10"
VAGRANT_JSON = JSON.parse(Pathname(__FILE__).dirname.join('nodes', '192.168.33.10.json').read)
config.vm.provision :chef_solo do |chef|
chef.cookbooks_path = ["cookbooks", "site-cookbooks"]
chef.roles_path = "roles"
chef.data_bags_path = "data_bags"
chef.provisioning_path = "/tmp/vagrant-chef"
chef.run_list = VAGRANT_JSON.delete('run_list')
chef.json = VAGRANT_JSON
end
end
Nows let bring up the machine
vagrant up
Note
Below you will notice I reference a user and SSH key generated by vagrant, to discover these I ran
vagrant ssh-config
First Chef run
We should be ready to provision our vanilla Linux machine.
(note: if using vagrant, this is already done when you ran vagrant up
)
First lets grab the cookbooks from Berkshelf
berks install
Now lets prepare the Linux machine
knife solo prepare -i ./.vagrant/machines/default/virtualbox/private_key vagrant@192.168.33.10
And finally, lets run the cookbooks to actually to the provisioning
knife solo cook -i ./.vagrant/machines/default/virtualbox/private_key vagrant@192.168.33.10
Subsequent Chef runs
Now all our ducks are in a row, we can make changes to recipes, nodes, etc. then just re-provision the machine like so
knife solo cook -i ./.vagrant/machines/default/virtualbox/private_key vagrant@192.168.33.10
If you introduced any more cookbooks from the super market you’ll need to run
berks install
Write a recipe
Now we have an machine to up and can cook upon it, it’s time to do a custom recipe.
As we are just hacking, lets just start by adding ruby code into site-cookbooks/workplace/recipes/default.rb
, if we were
clever we’d group different functions in different recipes allowing us to seperate the funtions into roles, but for now
lets just add the the ‘default.rb’
execute "echo 'hello world' > /tmp/a_test_file.txt"
execute
is one of Chef’s most basic methods, see Chef Docs for more
We’ve just created our 1st recipe, lets provison a server with it. (see above)