69

A current Chef recipe isn't running because of a bug in version 0.10.10. How can I upgrade the version of Chef that Vagrant uses, to 0.10.12?

I don't want to just update it for the current instance of the VM - I keep destroying and rebuilding those. Do I need to change something in the Vagrant base box, or something in my (physical) system's installation?

Steve Bennett
  • 114,604
  • 39
  • 168
  • 219

6 Answers6

104

Using the Vagrant plugin vagrant-omnibus worked great for me:

vagrant plugin install vagrant-omnibus

You can then simply configure your chef version in the Vagrantfile before doing the provisioning:

config.omnibus.chef_version = :latest

You can also specify a specific version:

config.omnibus.chef_version = '11.6.0'
mirkokiefer
  • 3,347
  • 4
  • 20
  • 25
  • 11
    This should be voted up, and possibly marked as the correct answer rather the older currently marked correct answer. – jimeh Aug 31 '13 at 08:38
  • Yes. This is the correct answer for the thread since it doesn't depend on the box being an Ubuntu machine. For a complete working example [check my repo](https://github.com/elgalu/jenkins-box-for-travis/blob/74c56b7/Vagrantfile#L25) – Leo Gallucci Nov 22 '13 at 14:01
  • Does this work if you replace `:latest` by a specific version? – Steve Bennett Mar 13 '14 at 04:34
  • yes, you can use `config.omnibus.chef_version = '11.6.0'` – ouranos Apr 03 '14 at 05:49
  • I have installed the plugin and added the line before the provision setting `config.omnibus.chef_version = :latest config.vm.provision :chef_solo do |chef| ` but chef solo is still seems to be using 10.26.0 and throwing the same error – Jeetendra Pujari Jul 24 '14 at 19:23
  • Beware that using `:latest` can result in failed deployments - use a stable version (like `11.6.0`) if you don't want surprises. – kikito Sep 17 '14 at 16:08
39

Add the lines

config.vm.provision :shell, :inline => 'apt-get install build-essential ruby1.9.1-dev --no-upgrade --yes'
config.vm.provision :shell, :inline => "gem install chef --version 11.4.2 --no-rdoc --no-ri --conservative"

to your Vagrantfile before your config.vm.provision :chef_solo block.

props to hauraki's comment on http://dougireton.com/blog/2012/12/23/automatically-upgrading-chef-client-on-vagrant-up/

edited to include Jason Mayfield's comment. Make sure and give him an upvote too. I added --no-upgrade to speed things up and match the --conservative on the second line. You could instead do what Jason did, and remove both the --no-upgrade and --conservative.

edited to include suggested edit by anonymous user228653

Bryan Larsen
  • 9,468
  • 8
  • 56
  • 46
  • Thanks - not in a position to test this at the moment, but sounds legit. (Note from the blog: Chef actually gets run twice, once to upgrade Chef, then once for real.) – Steve Bennett May 08 '13 at 01:09
  • actually, I think you can pretty much ignore the blog article. That's another solution, but the one that I picked out of the comments is short, sweet and effective. – Bryan Larsen May 08 '13 at 13:51
  • Note Jason Mayfield's comment below - if your VM image doesn't come with Ruby, you may need to add this line as well (before the above): `config.vm.provision :shell, inline: 'apt-get install ruby1.9.1-dev'` – Steve Bennett Aug 01 '13 at 01:44
  • I got to this answer and while it works, using the chef packages may be a cleaner way: `config.vm.provision :shell, :inline => 'wget -q https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef_11.6.2-1.ubuntu.12.04_amd64.deb -O /tmp/chef_11.6.2-1.ubuntu.12.04_amd64.deb'` `config.vm.provision :shell, :inline => "dpkg -i /tmp/chef_11.6.2-1.ubuntu.12.04_amd64.deb"` – coredump Oct 15 '13 at 03:44
31

Rebuild the base box. First, bring it up without provisioning and SSH to it.

vagrant up --no-provision 
vagrant ssh

Then, perform the commands you need to update the box. This can include updating Chef and Ruby. Optionally, update the packages for the OS, etc. You should clean up the box of everything that isn't required, such as downloaded package files or caches.

For example, I use the Opscode Omnibus Full Stack Installer for Chef in my Vagrant boxes (originally built with VeeWee), and I update the packages, too.

sudo dpkg --purge chef chef-full
sudo true && curl -L https://www.opscode.com/chef/install.sh | sudo bash
sudo apt-get update && sudo aptitude safe-upgrade
sudo rm /var/cache/apt/archives/*.deb

Don't forget to "zero" the disk to reduce the size.

# a bunch of commands like gem install chef, apt-get upgrade, whatever
sudo dd if=/dev/zero of=/EMPTY bs=1M
sudo rm /EMPTY
exit

Then, package the box up and add it to your Vagrant environment for use.

vagrant package
vagrant box add mynewlucid32 package.box

If you want to use the same box name, you'll need to remove the existing box (~/.vagrant.d/boxes/BOXNAME) first.

Eric Schoonover
  • 47,184
  • 49
  • 157
  • 202
jtimberman
  • 8,228
  • 2
  • 43
  • 37
  • You can find this and a few more commands in a postinstall.sh script here: https://gist.github.com/1052287 – StephenKing Nov 17 '12 at 10:36
  • FYI, instead of `wget -O - https://opscode.com/chef/install.sh | sudo bash` the following is the new [recommend](http://wiki.opscode.com/display/chef/Installing+Omnibus+Chef+Client+on+Linux+and+Mac) procedure. `sudo true && curl -L https://www.opscode.com/chef/install.sh | sudo bash` The former may lead to "unable to retrieve a valid package!' – pdeschen Feb 26 '13 at 17:26
12

There are a number of options you can specify when using Chef for provisioning. One of these is version, which allows you to specify the Chef version you want.

For example, see the chef.version line in this extract from a Vagrantfile of mine:

config.vm.provision :chef_solo do |chef|
   chef.version = "10.14.2"
   chef.cookbooks_path = "cookbooks"
   chef.add_recipe("vagrant_main")
 end
Sam
  • 5,997
  • 5
  • 46
  • 66
  • 2
    In my opinion this should be marked as the correct answer. Reasons: (1) it is independent either from external plugins and operating systems (2) makes it easier to standardize the development environments of your teams. – Mia Apr 28 '17 at 20:41
11

I am unable to post comments on answers, but I wanted to add a note to Bryan Larsen's answer above. In order to get his provisioning command to work, I needed to add a line before it to be able to build the gem native extensions during install of the new Chef version. Therefore, it became:

config.vm.provision :shell, inline: 'apt-get install ruby1.9.1-dev'
config.vm.provision :shell, inline: 'gem install chef --version 11.4.4 --no-rdoc --no-ri'

This was on Ubuntu 13.04, in case that matters to anyone.

Jason Mayfield
  • 121
  • 1
  • 2
0

If you are using Chef Test Kitchen, then you can specify the Chef version in .kitchen.yml file, like this:

provisioner:
  name: chef_zero
  require_chef_omnibus: 12.6.0
codeforester
  • 39,467
  • 16
  • 112
  • 140