/vagrant-chef

A small example setup for Vagrant/Chef

Primary LanguageRubyMIT LicenseMIT

vagrant-chef

A simple tutorial in using Vagrant and Chef for development and production

Requirements:

Chef

https://www.getchef.com/download-chef-client/

curl -L https://www.opscode.com/chef/install.sh | bash

knife solo

https://github.com/matschaffer/knife-solo#usage

gem install knife-solo

Berkshelf

https://github.com/berkshelf/berkshelf#installation

gem install berkshelf

Vagrant

https://docs.vagrantup.com/v2/installation/

vagrant-omnibus

https://github.com/opscode/vagrant-omnibus

vagrant plugin install vagrant-omnibus

vagrant-berkshelf

https://github.com/berkshelf/vagrant-berkshelf

vagrant plugin install vagrant-berkshelf --plugin-version 2.0.1

Vagrant

Init a new Vagrant machine with Ubuntu 14.04 64bit:

vagrant init ubuntu/trusty64

Berskfile

Create a Berksfile and a corresponding metadata.rb. These are needed for adding others recipes.

Create our first recipe

Add a folder named recipes and insert a default.rb This file contains the definition of our cookbook in the comment section

#
# Cookbook Name:: salad
# Recipe:: default
#

Add Cookbook definition to metadata.rb

name             'salad'
maintainer       'Markus Klepp'
maintainer_email 'khor@entwicklerbier.org'
license          'The MIT License (MIT)'
description      'Installs/Configures salad'
long_description 'Installs/Configures salad'
version          '0.1.0'

Link recipe with Vagrant

Enable omnibus installer in Vagrantfile:

config.omnibus.chef_version = '11.16'

Enable Berkshelf in Vagrantfile:

config.berkshelf.enabled = true

Define our recipe to run when VM gets provisioned

config.vm.provision :chef_solo do |chef|
    chef.json = {
    }

    chef.run_list = [
        "recipe[salad::default]"
    ]
  end

First boot of Vagrant machine

vagrant up

Add nginx to our cookbook

To install nginx, we use the nginx recipe from https://github.com/miketheman/nginx. Add nginx dependency to metadata.rb

depends 'nginx', '~> 2.7.4'

Create a new recipe named recipes/web_server.rb that includes the nginx recipe. It will also contain our basic configuration for the web server.

include_recipe 'nginx'

Add webserver recipe to our default recipe.

include_recipe 'web_server'

To cook our cookbook (in this case install nginx in its default state) just type:

vagrant provision

To access the now running nginx on http://localhost:8080 we need to forward the clients port 80 to the hosts port 8080 in our Vagrantfile.

config.vm.network "forwarded_port", guest: 80, host: 8080

To reload the Vagrantfile type:

vagrant reload

Create our own nginx site

Disable default nginx site in web_server.rb:

nginx_site 'default' do
  enable false
end

Create index.html.erb and nginx_site.erb in templates/default

Add lines to web_server.rb:

directory '/var/www/salad' do
  action :create
end

template '/var/www/salad/index.html' do
  source 'index.html.erb'
end

template "#{node['nginx']['dir']}/sites-available/salad" do
  source 'nginx_site.erb'
end

nginx_site 'salad' do
  enable true
end

After cooking we can visit our new nginx site on localhost:8080

vagrant provision

Upload to production server

You need a running VPS at the provider of your choice. I prepared a server under salad.entwicklerbier.org. To bootstrap Chef and install our recipe, we need the following command:

knife solo bootstrap root@salad.entwicklerbier.org

This command will install our cookbook, but does not run anything. To run the default recipe we need to set the content of nodes/salad.entwicklerbier.org to:

{
  "run_list": [
    "recipe[salad::default]"
  ]
}

To cook the cookbook on our node type:

knife solo cook root@salad.entwicklerbier.org

An error should be displayed, because of the order of the commands in the web_server recipe. We enable the salad site before it is defined. So lets move the nginx_site definition to the end of the file. Another run of the cook command will finish and make our site available under http://salad.entwicklerbier.org.

Different configuration for development and production

Say we want to enable a more verbose debug log on the development machine. We need to supply default value in attributes/default.rb

default['web_server']['debug_log'] = false

In our Vagrantfile add the debug_log=true config to the Chef config:

web_server: {
  debug_log: true
}

And alter our nginx_site.erb to use the advanced log:

error_log /var/log/nginx/error.log <%= 'debug' if node['web_server']['debug_log'] %>;

We can now provision our vagrant machine and cook on our node to apply these changes.

Deploying SSL-Certificates

Adapt your nginx-config to load the ssl certs.

You should really not put your unencrypted key files in a public repo. There are a couple of new steps in the webserver recipe to copy the certificate chain/key in position.

Provision and ssl :)