Even though there are many products that can do automated deployment and configuration the client choose Chef. The client is also leveraging lots of the Amazon Web Services but to keep costs down we have been using Vagrant to do the initial local development work before starting up EC2 instances. This also allows developers get the same baseline environment up and running, usually, very quickly before they start adding and changing the code.
Therefore we thought that we would share our observations and initial experience of Vagrant and Chef.
Starting point?
Once we got passed the initial setup instruction provide on the Vagrant site that was great as we was able to get the basic virtual server up and running within an hour but we found the documentation provide on the Chef a little confusing but as it was a great reference.
We found http://www.jedi.be/blog/2011/03/28/using-vagrant-as-a-team/ a really useful article and soon came up with the understanding that recipes are useful but it's actually the definition of the node that provides the starting point, this is the chef.run_list within the VagrantFile, that should contain a few basic baseline recipes but we would recommend it mainly contains roles. It is within a role that recipes should be used in conjunction with attribute overrides.
The following is our baseline VagrantFile that we have used a few times for defining development environment relies on chef-solo provisioning. This gets around some chef-solo mode issues and also updates the OS to use 0.10.04 version of Chef so documentation found online becomes a good reference:
# Start of file
#
USER = ENV['OPSCODE_USER'] || ENV['USER']
BASE_BOX = ENV['VAGRANT_BOX'] || 'lucid32'
CHEF_CONFIG_PATH = "../../chef"
Vagrant::Config.run do |config|
config.vm.box = BASE_BOX config.vm.box_url = "http://files.vagrantup.com/#{
config.vm.host_name = "#{USER}-vagrant"
config.vm.forward_port("web", 80, 8080)
config.vm.forward_port("web- secure", 443, 8443)
config.vm.forward_port(" database", 5432, 85432) # PostgreSQL
config.vm.forward_port("web-
config.vm.forward_port("
config.vm.provision :shell, :inline => "gem update chef"
config.vm.provision :chef_solo do |chef|
chef.node_name = "#{USER}-vagrant"
chef.cookbooks_path = "#{CHEF_CONFIG_PATH}/
chef.data_bags_path = "#{CHEF_CONFIG_PATH}/data_
chef.roles_path = "#{CHEF_CONFIG_PATH}/roles"
chef.provisioning_path = "/etc/chef"
chef.log_level = :debug
# adjust the run list to suit your testing needs
chef.run_list = [
"recipe[apt]",
"role[something]"
]
# You may also specify custom JSON attributes:
#chef.json= {}
end
end
#
# End Of File
#
(project name)
+ chef
| + cookbooks
| | + apt (recipe downloaded from http://community.opscode.com/cookbooks/apt)
| | + chef-solo-search (recipe downloaded from https://github.com/edelight/chef-solo-search/downloads)
| + data_bags
| + roles
| + something.json
+ vagrant
+ (server name)
+ VagrantFileThe key points to make chef-solo run like the chef client/server mode are:
- The shell provision to up grade the base lucid32 to use the latest chef.
- Adding the basic recipes and roles to the chef.run_list that would part of the node definition
- Having the chef-solo-search/library as a recipe
I am not a Ruby programmer
Chef is based on Ruby and therefore you use this to help structure the recipes, definitions and templetes used. This was okay but you need to be aware that JSON is used as part of the chef-solo mode when defining the roles and data_bags.
Useful Commands
Creating a virtual instance:
vagrant up
Updating the virtual instance with the latest chef provisioning:
vagrant provision
Removing a virtual instance:
vagrant destroy
Chef is based on Ruby and therefore you use this to help structure the recipes, definitions and templetes used. This was okay but you need to be aware that JSON is used as part of the chef-solo mode when defining the roles and data_bags.
Useful Commands
Creating a virtual instance:
vagrant up
Updating the virtual instance with the latest chef provisioning:
vagrant provision
Removing a virtual instance:
vagrant destroy