What is Chef? Chef is an automation platform for developers & systems engineers to continuously define, build, and manage infrastructure. CHEF USES: Recipes and Cookbooks that describe Infrastructure as Code. Chef enables people to easily build & manage complex & dynamic applications “ at massive scale • New model for describing infrastructure that promotes reuse • Programmatically provision and configure • ” Reconstruct business from code repository, data backup, and bare metal resources
Evolving towards Configuration Management •Just build it •Keep notes in server.txt •Move notes to the wiki •Custom scripts (in scm?!) •Snapshot & Clone
Building something with Chef •Come up with your policy •Abstract the resources •Write recipes •Apply recipes to nodes
Cookbook $ knife cookbook create website ** Creating cookbook website ** Creating README for cookbook: website ** Creating CHANGELOG for cookbook: website ** Creating metadata for cookbook: website
Resources in Recipe package "apache2" template "/var/www/index.html" do owner "www-data" group "www-data" mode 644 source "index.html.erb" end service "apache2" do action [:start, :enable] end
templates/default/index.html.erb <html> <head> <title><%= node['conference']['name'] %></title> </head> <body> <h1>Hello, <%= node['conference']['name'] %></h1> </body> </html> • I told you, this is a trivial example! Stick with me. • No, you wouldn’t really manage your content in Chef but this may be easier to grok than sysctl settings.
Apply This Recipe to a Node $ vagrant init web A `Vagrantfile` has been placed in this directory. You are now ready to `vagrant up` your first virtual environment! Please read the comments in the Vagrantfile as well as documentation on `vagrantup.com` for more information on using Vagrant.
Vagrantfile # -*- mode: ruby -*- # vi: set ft=ruby : Vagrant::Config.run do |config| config.vm.box = "web" config.vm.forward_port 80, 8080 config.vm.provision :chef_client do |chef| chef.chef_server_url = "https://api.opscode.com/organizations/bigruby" chef.validation_key_path = "bigruby-validator.pem" chef.validation_client_name = "bigruby-validator" end end
Launch the VM $ vagrant up [default] Importing base box 'web'... [default] Matching MAC address for NAT networking... [default] Forwarding ports... [default] -- 22 => 2222 (adapter 1) [default] -- 80 => 8080 (adapter 1) ... [2013-02-01T05:24:19+00:00] WARN: Node vagrant.vm has an empty run list. [2013-02-01T05:24:20+00:00] INFO: Chef Run complete in 1.962777136 seconds [2013-02-01T05:24:20+00:00] INFO: Running report handlers [2013-02-01T05:24:20+00:00] INFO: Report handlers complete
knife cookbook test $ knife cookbook test website checking website Running syntax check on website Validating ruby files Validating templates
Testing Tools • Vagrant • knife cookbook test • Foodcritic
Foodcritic • A lint tool for your Opscode Chef cookbooks • Flag problems in your Chef cookbooks that will cause Chef to blow up when you attempt to converge • Encourage discussion within the Chef community on the more subjective stuff - what does a good cookbook look like?
Foodcritic $ foodcritic cookbooks/website FC006: Mode should be quoted or fully specified when setting file permissions: cookbooks/website/recipes/default.rb:11 FC008: Generated cookbook metadata needs updating: cookbooks/website/metadata.rb:2 FC008: Generated cookbook metadata needs updating: cookbooks/website/metadata.rb:3
Chefspec require 'chefspec' describe 'website::default' do chef_run = ChefSpec::ChefRunner.new chef_run.converge "website::default" it "should install apache package" do chef_run.should install_package "apache2" end it "should create a home page" do chef_run.should create_file "/var/www/index.html" end
Chefspec it "should create a home page with our content" do chef_run.should create_file_with_content( "/var/www/index.html","Big Ruby") end it "should start the apache service" do chef_run.should start_service "apache2" end it "should enable the apache service" do chef_run.should enable_service "apache2" end end
Testing Tools • Vagrant • knife cookbook test • Foodcritic • Chefspec • Fauxhai • Minitest and the Minitest Chef Handler
Handlers $ vagrant up [default] Importing base box 'web'... [default] Matching MAC address for NAT networking... [default] Forwarding ports... [default] -- 22 => 2222 (adapter 1) [default] -- 80 => 8080 (adapter 1) ... [2013-02-01T05:24:19+00:00] WARN: Node vagrant.vm has an empty run list. [2013-02-01T05:24:20+00:00] INFO: Chef Run complete in 1.962777136 seconds [2013-02-01T05:24:20+00:00] INFO: Running report handlers [2013-02-01T05:24:20+00:00] INFO: Report handlers complete
minitest class TestWebsite < MiniTest::Chef::TestCase include MiniTest::Chef::Assertions include MiniTest::Chef::Context include MiniTest::Chef::Resources def test_succeed assert run_status.success? end
def test_that_the_package_installed package("apache2").must_be_installed end def test_that_the_service_is_running service("apache2").must_be_running end
minitest def test_that_the_service_is_enabled service("apache2").must_be_enabled end def test_home_page_file file("/var/www/index.html").must_exist end def test_home_page_content file("/var/www/index.html").must_include node['conference']['name'] end
Why Run $ knife ssh "chef_environment:staging" "sudo chef-client --why-run" Starting Chef Client, version 11.4.0 ... Converging 3 resources * package[apache2] action install - Would install version 2.2.22-1ubuntu1 of package apache2 * template[/var/www/index.html] action create * Parent directory /var/www does not exist. * Assuming directory /var/www would have been created - Would create template[/var/www/index.html] * service[apache2] action start - Would start service service[apache2] * service[apache2] action enable - Would enable service service[apache2] WARN: In whyrun mode, so NOT performing node save. Chef Client finished, 4 resources would have been updated
Why Run • Promises, Lies, and Dry-Run Mode • http://bit.ly/guessrun • Why Run reported 4 resource updated • “real run” only 2 resources are updated
Testing Tools • Vagrant - Local development and testing • knife cookbook test - Verify ruby syntax • Foodcritic - Cookbook linter • Chefspec - Unit testing recipes • Fauxhai - Mock all the things • Minitest Chef Handler - post-converge tests • Why-run - Best guess
Moar Testing Tools • Test Kitchen • Cross-platform testing • Cucumber Chef • acceptance & integration testing