Rails development using Vagrant and Chef-zero

With every engineer, deployment's truly a nightmere when they have to deal with so many chalanges including infrastructure, environment setting ... but appearance of Chef makes everything to become more esily.

However, Chef isn't a miracle that can resolve everything. When the system becomes more larger with series of servers and enormous data, the gap between two environemtn: production and development's exponential. That's why we need a new development environment to mimic production mode.

In this post, I'll make a sample development environment for Ruby on Rails based on Vargrant and Chef-zero. Notice that there're many way to build Rails environment with Chef and Vagrant and this is just one of that.

1. Basic Setup

I do this tutorial using OS X 10.10 Yosemite and there are lightly differences between other OS due to insufficient packages. Basically, Vituralbox and Vagrant provide a virtual machine while Chef help us to setup that machine

Software installation

  • Virtualbox: download the latest version from official website.
  • Chef: The Chef package now's is avaiable in https://downloads.chef.io/chef-dk/
  • Vargrant: install from the package in website or from brew cast brew cask install vagrant

Vagrant plugins

$vagrant plugin install vagrant-vbguest
$vagrant plugin install vagrant-omnibus
$vagrant plugin install vagrant-berkshelf
$vagrant plugin install vagrant-chef-zero
  • Omnibus provides both a DSL as well as a command-line tool for generating installer artifacts from that definition.

  • vbguest vagrant-vbguest is a Vagrant plugin which automatically installs the host's VirtualBox Guest Additions on the guest system.

  • Berkshelf Manage a Cookbook or an Application's Cookbook dependencies

  • Chef-zero is a simple, easy-install, in-memory Chef server that can be useful for Chef Client testing and chef-solo-like tasks that require a full Chef Server

Chef setup

As chef comes with its own ruby, we’ve to modify our PATH and Gem env to reference it. So get the result of the ‘chef shell-init bash’ and paste it in your ~/.bash_profile file (you can change the PATH variable to [everything chef related]:$PATH

2. Create Vagrant box

Anyone having experiences with virtula machine know that to setup new machine need many steps from resource allocation to network configuration. But with Vagrant, just few commands and single file are enough.

  • Create a project and intialize vagrant
$ mkdir rails-chef
$ cd rails-chef
$ vagrant init

After that, we'll have a Vagrantfile inside new project folder

  • Inside Vagrantfile, we need some basic setup for new machine
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
      # Use Ubuntu 14.04 Trusty Tahr 64-bit as our operating system
      config.vm.box = "ubuntu/trusty64"
      config.vm.provider :virtualbox do |vb|
        vb.customize ["modifyvm", :id, "--memory", "1024"]
      end

      # Forward the Rails server default port to the host
      config.vm.network :private_network, ip: "33.33.33.33"
      config.vm.hostname = "chef-rails"
end

Based on requirement, we can modify some parametters such as Operating System, memory or network configuration

  • Turn on the box and wait for installing new box
$vagrant up
  • Connect to Vagrantbox through SSH
$vagrant ssh

Now a new Vagrantbox's ready for us to implement new project

3. Environment setting with Chef

"Vagrant is easy - Chef is hard" is true. To understand the Chef concept, we have to spend long hours with knowledge and some practices and I don't have enough spaces and times to start from the beginning. Thereofore, in this part, I'll concentrate into building environment based on Chef-zero and using cookbooks.

Create new chef-repo

$ chef generate repo chef-repo
$ cd chef-repo

Structure of chef-repo

├── LICENSE
├── README.md
├── chefignore
├── cookbooks
│   ├── README.md
│   └── example
│       ├── attributes
│       │   └── default.rb
│       ├── metadata.rb
│       └── recipes
│           └── default.rb
├── data_bags
│   ├── README.md
│   └── example
│       └── example_item.json
├── environments
│   ├── README.md
│   └── example.json
└── roles
    ├── README.md
    └── example.json

For easily manage the cookbook and dependencies of Chef, we need to create a Berksfile. This file also can refer as a Gemfile in Ruby on Rails project that help us to download and install the cookbooks and dependencies from the market. So, what're cookbooks that we need?

$ vi Berksfile
source "https://supermarket.chef.io"

cookbook 'application_ruby'
cookbook 'apt'
cookbook 'build-essential'
cookbook 'user'
cookbook 'ssh_known_hosts'
cookbook 'ruby_build'
cookbook 'vim'

These're basic cookbooks sufficient for Rails development. For more detail or each cookbook, let visit https://supermarket.chef.io/ To install cookbooks, just enter a command

$ berks vendor cookbooks

And now, all the needed cookbooks are downloaded into folder chef-repo/cookbooks

Create a cookbook for Rails Stack

(This part are updating)