•Environment per project •Dev ~= Test ~= Staging ~= Prod •Easy to define & transport •Easy to tear down •Provisionable: infrastructure as code •Versionable •Shared across the team
•Select base box •Choose virtualization provider •Configure VM parameters •Configure networking •Tweak SSH settings •Mount local folders •Provision machine What does a Vagrantfile do?
$"vagrant"up Bringing"machine"'default'"up"with"'virtualbox'"provider... [default]"VirtualBox"VM"is"already"running. $"vagrant"status Current"machine"states: default""""""""""""""""""running"(virtualbox) When VM exists & is running
#".*."mode:"ruby".*. #"vi:"set"ft=ruby": Vagrant.configure("2")"do"|config| ""config.vm.box"=""precise32" ""config.vm.box_url"=""http:// files.vagrantup.com/precise32.box""" end You probably remember this one
config.vm.network":forwarded_port,"guest:"80,"host:"8080 config.vm.network":public_network config.vm.network":private_network,"ip:""192.168.10.10" Networking Bridged network Port forwarding Private IP space
#".*."mode:"ruby".*. #"vi:"set"ft=ruby": Vagrant.configure("2")"do"|config| ""config.vm.box"=""precise32" ""config.vm.box_url"=""http://files.vagrantup.com/ precise32.box""" ""config.vm.network":private_network,"ip:""192.168.10.10" end $"vagrant"up ... [default]"Preparing"network"interfaces"based"on" configuration... [default]"Forwarding"ports... [default]".."22"=>"2222"(adapter"1) Yes, there is port forwarding involved
$"vagrant"up ... [default]"Mounting"shared"folders... [default]".."/vagrant config.vm.synced_folder""web/",""/var/www" $"vagrant"up ... [default]"Mounting"shared"folders... [default]".."/vagrant [default]".."/var/www Extra mount Default mount
Shell Vagrant.configure("2")"do"|config| ""config.vm.provision""shell","path:""script.sh" end Point to script in your current folder Vagrant.configure("2")"do"|config| ""config.vm.provision""shell","path:""https:// example.com/provisioner.sh" end Point to external script
•Written in Ruby •Open source with enterprise revenue model •Similar features •Both have a standalone and server-side edition •Supported by a large community •Modularized components •Use packages for software installs •Use templating for custom files •Filesystem methods •... Chef & Puppet
Chef vs Puppet Chef Puppet Modules Actions Language Running order Approach Programming style Cookbooks Modules Recipes Manifests Ruby extended with DSL DSL Sequential “Random” Define actions Define state Procedural “OO-like”
•Download cookbooks (https://github.com/opscode-cookbooks) •Configure chef.cookbooks_path in Vagrantfile •Add recipes using chef.add_recipe in Vagrantfile •Configure attributes with chef.json •Group custom actions in custom cookbook How to use Chef Solo
MySQL server recipe ... group"'mysql'"do ""action":create end user"'mysql'"do ""comment"'MySQL"Server' ""gid"""""'mysql' ""system""true ""home""""node['mysql']['data_dir'] ""shell"""'/sbin/nologin' end node['mysql']['server']['packages'].each"do"|name| ""package"name"do """"action""":install """"notifies":start,"'service[mysql]',":immediately ""end end ...
Let’s do it ourselves execute"'update"apt'"do """"command""apt.get"update" """"action":run end package"'mysql.server'"do """"action""":install """"notifies":start,"'service[mysql]',":immediately end package"'apache2'"do """"action""":install """"notifies":start,"'service[apache2]',":delayed end package"'php5'"do """"action""":install """"notifies":reload,"'service[apache2]',":delayed end ./tools/chef/cookbooks/project/recipes/default.rb
Let’s do it ourselves execute"'assign.root.password'"do """"command""/usr/bin/mysqladmin".u"root"password"'#{node['project'] ['server_root_password']}'" """"action":run """"only_if""/usr/bin/mysql".u"root".e"'show"databases;'" end service"'mysql'"do """"service_name"'mysql' """"supports":status"=>"true,":restart"=>"true,":reload"=>"true """"action""":enable end service"'apache2'"do """"service_name"'apache2' """"supports":status"=>"true,":restart"=>"true,":reload"=>"true """"action""":enable end ./tools/chef/cookbooks/project/recipes/default.rb
•Download modules (https://github.com/puppetlabs/) •Configure puppet.module_path, puppet.manifests_path & puppet.manifest_file in Vagrantfile •Provisioning flow happens in the main manifest •Configure attributes with puppet.facter How to use Puppet Apply
•Provisioning is often slow (especially when installing lots of packages) •Quality of public cookbooks/manifests •Support on cookbooks/manifests •Writing it yourself can be difficult •Some cookbooks/manifests only work on certain Linux distros Problems with provisioning
Re-distribute current VM $"vagrant"package •Possible solution for slow provisioning •Is not the same as vagrant box repackage •Use exported box as new base box •No provisioning required on startup •Possibility of doing “light” provisioning instead
vagrant"up vagrant"ssh vagrant"destroy vagrant"up"web vagrant"ssh"web vagrant"destroy"web vagrant"up"db vagrant"ssh"db vagrant"destroy"db All VM’s Primary VM All VM’s