Vagrant, Puppet & Chef #FTW

Ca901ddcea38854b9783781c91fc87c9?s=47 Thijs Feryn
November 19, 2013

Vagrant, Puppet & Chef #FTW

ZendConEU 2013 talk about Vagrant, Puppet & Chef

Ca901ddcea38854b9783781c91fc87c9?s=128

Thijs Feryn

November 19, 2013
Tweet

Transcript

  1. None
  2. Hi, my name is Thijs

  3. Et j’ai un joli accent belge

  4. I’m @ThijsFeryn on Twitter

  5. I’m an at Evangelist

  6. I’m a at board member

  7. h"ps://joind.in/9259 Please& give&me& feedback

  8. None
  9. Create and configure lightweight, reproducible, and portable development environments.

  10. Written in Ruby By Mitchell Hashimoto in 2010

  11. A layer on top of

  12. None
  13. None
  14. WHY? WHY? WHY?

  15. None
  16. •Environment per project •Dev ~= Test ~= Staging ~= Prod

    •Easy to define & transport •Easy to tear down •Provisionable: infrastructure as code •Versionable •Shared across the team
  17. $"vagrant Usage:"vagrant"[.v]"[.h]"command"[<args>] """".v,"..version""Print"the"version"and"exit. """".h,"..help"""""Print"this"help. Available"subcommands: """""box """""destroy """""halt """""init """""package

    """""plugin """""provision """""reload """""resume """""ssh """""ssh.config """""status """""suspend """""up
  18. $"vagrant"init".h Usage:"vagrant"init"[box.name]"[box.url] Generates a Vagrantfile

  19. •Select base box •Choose virtualization provider •Configure VM parameters •Configure

    networking •Tweak SSH settings •Mount local folders •Provision machine What does a Vagrantfile do?
  20. $"vagrant"init 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. #".*."mode:"ruby".*.

    #"vi:"set"ft=ruby": Vagrant.configure("2")"do"|config| ""config.vm.box"=""base" end
  21. $"vagrant"init"precise32"http:// files.vagrantup.com/precise32.box 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.

    #".*."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
  22. $vagrant"up Bringing"machine"'default'"up"with"'virtualbox'"provider... [default]"Box"'precise32'"was"not"found."Fetching"box"from"specified"URL"for the"provider"'virtualbox'."Note"that"if"the"URL"does"not"have a"box"for"this"provider,"you"should"interrupt"Vagrant"now"and"add the"box"yourself."Otherwise"Vagrant"will"attempt"to"download"the full"box"prior"to"discovering"this"error. Downloading"or"copying"the"box... Extracting" box...################################################################%"

    (Rate:"/s,"Estimated"time"remaining:")) Successfully"added"box"'precise32'"with"provider"'virtualbox'! [default]"Importing"base"box"'precise32'... [default]"Matching"MAC"address"for"NAT"networking... [default]"Setting"the"name"of"the"VM... [default]"Clearing"any"previously"set"forwarded"ports... [default]"Creating"shared"folders"metadata... [default]"Clearing"any"previously"set"network"interfaces... [default]"Preparing"network"interfaces"based"on"configuration... [default]"Forwarding"ports... [default]".."22"=>"2222"(adapter"1) [default]"Booting"VM... [default]"Waiting"for"VM"to"boot."This"can"take"a"few"minutes. [default]"VM"booted"and"ready"for"use! [default]"Configuring"and"enabling"network"interfaces... [default]"Mounting"shared"folders... [default]".."/vagrant
  23. Boxes

  24. http://vagrantbox.es

  25. https://github.com/ jedi4ever/veewee Build your own boxes

  26. $"vagrant"box Usage:"vagrant"box"<command>"[<args>] Available"subcommands: """""add """""list """""remove """""repackage

  27. $"vagrant"box"list precise32"""""""(virtualbox) $"vagrant"box"remove"precise32"virtualbox Removing"box"'precise32'"with"provider"'virtualbox'... $"vagrant"box"add"precise32"http://files.vagrantup.com/ precise32.box"..provider"virtualbox Downloading"or"copying"the"box... Extracting" box...##################################################### ###########%"(Rate:"/s,"Estimated"time"remaining:"))

    Successfully"added"box"'precise32'"with"provider" 'virtualbox'! $"vagrant"box"repackage"precise32"virtualbox $"ls".lh .rw.r..r..""1"thijs""staff"""275M"10"okt"16:06"package.box
  28. $"vagrant"box"list precise32"""""""(virtualbox) $"vagrant"box"remove"precise32"virtualbox Removing"box"'precise32'"with"provider"'virtualbox'... $"vagrant"box"add"precise32"http://files.vagrantup.com/ precise32.box"..provider"virtualbox Downloading"or"copying"the"box... Extracting" box...##################################################### ###########%"(Rate:"/s,"Estimated"time"remaining:"))

    Successfully"added"box"'precise32'"with"provider" 'virtualbox'! $"vagrant"box"repackage"precise32"virtualbox $"ls".lh .rw.r..r..""1"thijs""staff"""275M"10"okt"16:06"package.box #".*."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 Vagrantfile can do this too
  29. $"tar"xvzf"package.box x"./box.disk1.vmdk x"./box.ovf x"./metadata.json x"./Vagrantfile Content of a box file

  30. Vagrant up & running

  31. $"vagrant"up Bringing"machine"'default'"up"with"'virtualbox'"provider... [default]"Importing"base"box"'precise32'... [default]"Matching"MAC"address"for"NAT"networking... [default]"Setting"the"name"of"the"VM... [default]"Clearing"any"previously"set"forwarded"ports... [default]"Creating"shared"folders"metadata... [default]"Clearing"any"previously"set"network"interfaces... [default]"Preparing"network"interfaces"based"on"configuration... [default]"Forwarding"ports...

    [default]".."22"=>"2222"(adapter"1) [default]"Booting"VM... [default]"Waiting"for"VM"to"boot."This"can"take"a"few"minutes. [default]"VM"booted"and"ready"for"use! [default]"Configuring"and"enabling"network"interfaces... [default]"Mounting"shared"folders... [default]".."/vagrant When VM doesn’t exist
  32. $"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
  33. $"vagrant"suspend [default]"Saving"VM"state"and"suspending"execution... $"vagrant"status Current"machine"states: default""""""""""""""""""saved"(virtualbox) $"vagrant"up Bringing"machine"'default'"up"with"'virtualbox'"provider... [default]"Resuming"suspended"VM... [default]"Booting"VM... [default]"Waiting"for"VM"to"boot."This"can"take"a"few"

    minutes. [default]"VM"booted"and"ready"for"use! Suspend & resume
  34. $"vagrant"halt [default]"Attempting"graceful"shutdown"of"VM... $"vagrant"status Current"machine"states: default""""""""""""""""""poweroff"(virtualbox) $"vagrant"up Bringing"machine"'default'"up"with"'virtualbox'"provider... [default]"Setting"the"name"of"the"VM... [default]"Clearing"any"previously"set"forwarded"ports... [default]"Creating"shared"folders"metadata...

    [default]"Clearing"any"previously"set"network"interfaces... [default]"Preparing"network"interfaces"based"on"configuration... [default]"Forwarding"ports... [default]".."22"=>"2222"(adapter"1) [default]"Booting"VM... [default]"Waiting"for"VM"to"boot."This"can"take"a"few"minutes. [default]"VM"booted"and"ready"for"use! [default]"Configuring"and"enabling"network"interfaces... [default]"Mounting"shared"folders... [default]".."/vagrant Stop & start
  35. $"vagrant"destroy Are"you"sure"you"want"to"destroy"the"'default'"VM?"[y/N]"y [default]"Forcing"shutdown"of"VM... [default]"Destroying"VM"and"associated"drives... $"vagrant"status Current"machine"states: default""""""""""""""""""not"created"(virtualbox) Destroy

  36. Connect

  37. $"vagrant"ssh Linux"debian.7"3.2.0.4.amd64"#1"SMP"Debian"3.2.46.1"x86_64 The"programs"included"with"the"Debian"GNU/Linux"system"are" free"software; the"exact"distribution"terms"for"each"program"are"described" in"the individual"files"in"/usr/share/doc/*/copyright. Debian"GNU/Linux"comes"with"ABSOLUTELY"NO"WARRANTY,"to"the" extent permitted"by"applicable"law.

    Last"login:"Mon"Jul"15"13:13:36"2013"from"10.0.2.2 vagrant@debian.7:~$"sudo"su root@debian.7:/home/vagrant No login or password required
  38. root@debian.7:/home/vagrant#"cat".ssh/authorized_keys ssh.rsa" AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8 YVr+kz4TjGYe7gHzIw +niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6Iedp lqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7P tixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL +GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm +R4LOzFUGaHqHDLKLX +FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ=="

    vagrant"insecure"public"key Public key
  39. $"vagrant"ssh.config Host"default ""HostName"127.0.0.1 ""User"vagrant ""Port"2222 ""UserKnownHostsFile"/dev/null ""StrictHostKeyChecking"no ""PasswordAuthentication"no ""IdentityFile""/Users/thijs/.vagrant.d/insecure_private_key" ""IdentitiesOnly"yes

    ""LogLevel"FATAL Username, host, port & private key location
  40. $"cat"~/.vagrant.d/insecure_private_key .....BEGIN"RSA"PRIVATE"KEY..... MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2 hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1 Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf

    TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf 4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX 3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj 3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+ dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz 6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH +vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s= .....END"RSA"PRIVATE"KEY..... Private key
  41. The portability of a Vagrantfile

  42. Add Vagrantfile to VCS

  43. Share Vagrantfile Share dev env

  44. Infrastructure as code

  45. #".*."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
  46. Networking

  47. 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
  48. #".*."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
  49. #".*."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":forwarded_port,"guest:"80,"host:"8080 end $"vagrant"up ...

    [default]"Preparing"network"interfaces"based"on" configuration... [default]"Forwarding"ports... [default]".."22"=>"2222"(adapter"1) [default]".."80"=>"8080"(adapter"1) There’s port 80
  50. #".*."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":public_network end

  51. $"vagrant"up ... Bringing"machine"'default'"up"with"'virtualbox'" provider... [default]"Clearing"any"previously"set"forwarded"ports... [default]"Creating"shared"folders"metadata... [default]"Clearing"any"previously"set"network" interfaces... [default]"Available"bridged"network"interfaces: 1)"en1:"Wi.Fi"(AirPort)

    2)"en0:"Ethernet 3)"p2p0 What"interface"should"the"network"bridge"to?"1 [default]"Preparing"network"interfaces"based"on" configuration... [default]"Forwarding"ports... [default]".."22"=>"2222"(adapter"1) Choose interface
  52. config.vm.network""public_network",":bridge"=>"'en1:"Wi. Fi"(AirPort)' Assign interface in Vagrantfile

  53. Synced folders

  54. Local filesystem available in VM

  55. Save directly from your editor/IDE

  56. $"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
  57. VM properties

  58. config.vm.hostname"=""mymachine" config.vm.provider":virtualbox"do"|v| ""v.customize"["modifyvm",":id,"'..chipset',"'ich9'] ""v.customize"["modifyvm",":id,""..natdnshostresolver1",""on"] ""v.customize"["modifyvm",":id,""..ioapic",""on"] ""v.customize"["modifyvm",":id,""..memory","2048] ""v.customize"["modifyvm",":id,""..cpus",""4"] ""#v.gui"="true end VM

    properties
  59. Provisioning

  60. •Add specific software •Create configuration files •Execute commands •Create users

    •Manage services •Automatically executed on vagrant up Provisioning
  61. Having an exact copy of your production environment

  62. •Shell •Ansible •Chef Solo •Chef Client •Puppet Apply •Puppet Agent

    Provisioning
  63. Shell

  64. Shell config.vm.provision":shell,":inline"=>""mount" .t"tmpfs".o"size=50m,mode=0777"tmpfs"/vagrant/ app/cache" Mount RAM disk volume

  65. Shell $script"="<<SCRIPT echo"I"am"provisioning... date">"/etc/vagrant_provisioned_at SCRIPT Vagrant.configure("2")"do"|config| ""config.vm.provision""shell","inline:"$script end Inject Ruby

  66. 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
  67. None
  68. Written in Ruby By Opscode in 2009

  69. Written in Ruby By Puppet Labs in 2005

  70. •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
  71. 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”
  72. Let’s do some Chef!

  73. •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
  74. config.vm.provision":chef_solo"do"|chef| """chef.cookbooks_path"="./tools/chef/cookbooks" """chef.add_recipe""mysql::server" """chef.json"="{" """""mysql""=>"{ """""""""server_root_password""=>""foo", """""""""server_repl_password""=>""foo", """""""""server_debian_password""=>""foo" """""}"""""""""""""" """}

    end Vagrantfile
  75. Cookbook layout cookbook ├──"README.md ├──"attributes ├──"definitions ├──"files │"""└──"default ├──"libraries ├──"metadata.rb

    ├──"providers ├──"recipes │"""└──"default.rb ├──"resources └──"templates """"└──"default
  76. MySQL attributes default['mysql']['port']"""""""""""""""""""""""="3306 default['mysql']['nice']"""""""""""""""""""""""="0 case"node['platform_family'] when"'debian' ""default['mysql']['server']['packages']""""="%w[mysql.server] ""default['mysql']['service_name']""""""""""="'mysql' ""default['mysql']['basedir']"""""""""""""""="'/usr' ""default['mysql']['data_dir']""""""""""""""="'/var/lib/mysql'

    ""default['mysql']['root_group']""""""""""""="'root' ""default['mysql']['mysqladmin_bin']""""""""="'/usr/bin/mysqladmin' ""default['mysql']['mysql_bin']"""""""""""""="'/usr/bin/mysql' ""default['mysql']['conf_dir']""""""""""""""="'/etc/mysql' ""default['mysql']['confd_dir']"""""""""""""="'/etc/mysql/conf.d' ""default['mysql']['socket']""""""""""""""""="'/var/run/mysqld/ mysqld.sock' ""default['mysql']['pid_file']""""""""""""""="'/var/run/mysqld/ mysqld.pid' ""default['mysql']['old_passwords']"""""""""="0 ""default['mysql']['grants_path']"""""""""""="'/etc/mysql/grants.sql' ...
  77. 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 ...
  78. MySQL template [client] host"""""="localhost user"""""="debian.sys.maint password"="<%="node['mysql']['server_debian_password']"%> socket"""="<%="node['mysql']['socket']"%> [mysql_upgrade] host"""""="localhost user"""""="debian.sys.maint

    password"="<%="node['mysql']['server_debian_password']"%> socket"""="<%="node['mysql']['socket']"%> basedir""="/usr
  79. •Cron •Directory •Execute •File •Git •Group •Link •Log •Package •Service

    •Template •User •... Typical Chef resources
  80. 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
  81. 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
  82. Let’s do it ourselves #".*."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.synced_folder""web/",""/var/www" config.vm.provision":chef_solo"do"|chef chef.cookbooks_path"="./tools/chef/cookbooks" chef.add_recipe""project" chef.json"="{" "project""=>"{ "server_root_password""=>""foo" }"""""""""""""" } end" end
  83. $"vagrant"up ... [default]"Mounting"shared"folders... [default]".."/vagrant [default]".."/tmp/vagrant.chef.1/chef.solo.1/cookbooks [default]"Running"provisioner:"chef_solo... Generating"chef"JSON"and"uploading... Running"chef.solo... ... Provisioning

  84. [2013.10.21T10:37:22+00:00]"INFO:"***"Chef"11.4.4"*** [2013.10.21T10:37:22+00:00]"INFO:"Setting"the"run_list"to" ["recipe[project]"]"from"JSON [2013.10.21T10:37:22+00:00]"INFO:"Run"List"is"[recipe[project]] [2013.10.21T10:37:22+00:00]"INFO:"Run"List"expands"to"[project] [2013.10.21T10:37:22+00:00]"INFO:"Starting"Chef"Run"for"debian.7.1.0 [2013.10.21T10:37:22+00:00]"INFO:"Running"start"handlers [2013.10.21T10:37:22+00:00]"INFO:"Start"handlers"complete. [2013.10.21T10:37:24+00:00]"INFO:"Processing"package[mysql.server]"action" install"(project::default"line"1)

    [2013.10.21T10:37:59+00:00]"INFO:"package[mysql.server]"sending"start" action"to"service[mysql]"(immediate) [2013.10.21T10:37:59+00:00]"INFO:"Processing"service[mysql]"action"start" (project::default"line"10) [2013.10.21T10:37:59+00:00]"INFO:"Processing"execute[assign.root.password]" action"run"(project::default"line"5) [2013.10.21T10:37:59+00:00]"INFO:"execute[assign.root.password]"ran" successfully [2013.10.21T10:37:59+00:00]"INFO:"Processing"service[mysql]"action"enable" (project::default"line"10) [2013.10.21T10:37:59+00:00]"INFO:"Chef"Run"complete"in"37.208173462"seconds [2013.10.21T10:37:59+00:00]"INFO:"Running"report"handlers [2013.10.21T10:37:59+00:00]"INFO:"Report"handlers"complete
  85. Let’s do some Puppet!

  86. •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
  87. config.vm.provision":puppet"do"|puppet| """puppet.manifests_path"=""./tools/puppet/manifests" """puppet.module_path"=""./tools/puppet/modules" """puppet.manifest_file""=""init.pp" """puppet.options"="['..verbose'] end Vagrantfile include"mysql::server init.pp class"{"'::mysql::server':

    ""root_password"=>"'foo' } Override password Default
  88. Module layout module ├──"README.md ├──"files ├──"lib ├──"metadata.json ├──"spec ├──"manifests │"""└──"init.pp

    │"""└──"params.pp ├──"resources └──"templates └──"tests
  89. MySQL params class"mysql::params"{ ""$manage_config_file"""""="true ""$old_root_password""""""="'' ""$purge_conf_dir"""""""""="false ""$restart""""""""""""""""="false ""$root_password""""""""""="'UNSET' ""$server_package_ensure""="'present' ""$server_service_manage""="true

    ""$server_service_enabled"="true ""#"mysql::bindings ""$bindings_enable"""""""""="false ""$java_package_ensure"""""="'present' ""$java_package_provider"""="undef ""$perl_package_ensure"""""="'present' ""$perl_package_provider"""="undef ""$php_package_ensure""""""="'present' ""$php_package_provider""""="undef ""$python_package_ensure"""="'present' ""$python_package_provider"="undef ""$ruby_package_ensure"""""="'present' ""$ruby_package_provider"""="undef
  90. MySQL params 2 ... case"$::osfamily"{ """"'RedHat':"{ """"""if"$::operatingsystem"=="'Fedora'"and" (is_integer($::operatingsystemrelease)"and"$::operatingsystemrelease">=" 19"or"$::operatingsystemrelease"==""Rawhide")"{ """"""""$client_package_name"="'mariadb'

    """"""""$server_package_name"="'mariadb.server' """"""}"else"{ """"""""$client_package_name"="'mysql' """"""""$server_package_name"="'mysql.server' """"""} """"""$basedir"""""""""""""="'/usr' """"""$config_file"""""""""="'/etc/my.cnf' """"""$datadir"""""""""""""="'/var/lib/mysql' """"""$log_error"""""""""""="'/var/log/mysqld.log' """"""$pidfile"""""""""""""="'/var/run/mysqld/mysqld.pid' """"""$root_group""""""""""="'root' """"""$server_service_name"="'mysqld' """"""$socket""""""""""""""="'/var/lib/mysql/mysql.sock' """"""$ssl_ca""""""""""""""="'/etc/mysql/cacert.pem' """"""$ssl_cert""""""""""""="'/etc/mysql/server.cert.pem' """"""$ssl_key"""""""""""""="'/etc/mysql/server.key.pem'
  91. MySQL server manifest class"mysql::server"( ""$config_file"""""""""""""="$mysql::params::config_file, ""$manage_config_file""""""="$mysql::params::manage_config_file, ""$old_root_password"""""""="$mysql::params::old_root_password, ""$override_options""""""""="{}, ""$package_ensure""""""""""="$mysql::params::server_package_ensure, ""$package_name""""""""""""="$mysql::params::server_package_name,

    ""$purge_conf_dir""""""""""="$mysql::params::purge_conf_dir, ""$remove_default_accounts"="false, ""$restart"""""""""""""""""="$mysql::params::restart, ""$root_group""""""""""""""="$mysql::params::root_group, ""$root_password"""""""""""="$mysql::params::root_password, ""$service_enabled"""""""""=" $mysql::params::server_service_enabled, ""$service_manage""""""""""="$mysql::params::server_service_manage, ""$service_name""""""""""""="$mysql::params::server_service_name, ""$service_provider""""""""=" $mysql::params::server_service_provider, ""#"Deprecated"parameters ""$enabled"""""""""""""""""="undef, ""$manage_service""""""""""="undef )"inherits"mysql::params"{ ...
  92. MySQL template [client] user=root host=localhost <%"unless"scope.lookupvar('mysql::server::root_password')" =="'UNSET'".%> password='<%=" scope.lookupvar('mysql::server::root_password')"%>' <%"end".%>

    socket=<%="@options['client']['socket']".%> ERB style too!
  93. •Computer •Cron •Exec •File •Filebucket •Group •Host •Interface •Package •Service

    •Sshkey •User Typical Puppet resources
  94. Let’s do it ourselves exec"{""apt.update": """"command"=>""/usr/bin/apt.get"update", } package"{"'mysql.server': """"ensure""=>"present, """"require"=>"Exec['apt.update'],

    """"notify"=>"Service['mysql'], } package"{"'apache2': """"ensure""=>"present, """"require"=>"Exec['apt.update'], """"notify"=>"Package['php5'], } package"{"'php5': """"ensure""=>"present, """"require"=>"Exec['apt.update'], """"notify"=>"Service['apache2'], } ./tools/puppet/manifests/init.pp
  95. Let’s do it ourselves exec"{"'assign.root.password': """"command"=>""/usr/bin/mysqladmin".u"root"password"$root_password", """"require"=>"Package["mysql.server"], """"onlyif""=>""/usr/bin/mysql".u"root".e"'show"databases;'" } """"

    service"{""mysql": """"name"""""""=>""mysql", """"ensure"""""=>"running, """"enable"""""=>"true, """"hasrestart"=>"true, """"require""""=>"Package["mysql.server"], }"""" service"{""apache2": """"name"""""""=>""apache2", """"ensure"""""=>"running, """"enable"""""=>"true, """"hasrestart"=>"true, """"require""""=>"Package["apache2"], } ./tools/puppet/manifests/init.pp
  96. Let’s do it ourselves #".*."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.synced_folder""web/",""/var/www" config.vm.provision":puppet"do"|puppet| """puppet.manifests_path"=""puppet/manifests" """puppet.module_path"=""puppet/modules" """puppet.manifest_file""=""init.pp" """puppet.facter"="{ """"root_password""=>""foo", """} """puppet.options"="['..verbose'] end" end
  97. $"vagrant"up ... [default]"Mounting"shared"folders... [default]".."/vagrant [default]".."/tmp/vagrant.puppet/manifests [default]".."/tmp/vagrant.puppet/modules.0 [default]"Running"provisioner:"puppet... Running"Puppet"with"init.pp... Notice:"/Stage[main]//Exec[apt.update]/returns:"executed" successfully

    Notice:"/Stage[main]//Package[mysql.server]/ensure:"ensure" changed"'purged'"to"'present' Service[mysql] Notice:"/Stage[main]//Service[mysql]:"Triggered"'refresh'"from" 1"events Notice:"/Stage[main]//Exec[assign.root.password]/returns:" executed"successfully Notice:"/Stage[main]//Package[apache2]/ensure:"ensure"changed" 'purged'"to"'present' Notice:"/Stage[main]//Package[php5]/ensure:"ensure"changed" 'purged'"to"'present' Notice:"/Stage[main]//Service[apache2]:"Triggered"'refresh'" from"1"events Notice:"Finished"catalog"run"in"222.55"seconds Provisioning
  98. Re-provision VM $"vagrant"provision When machine is running

  99. Chef or Puppet?

  100. Problems with provisioning

  101. •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
  102. 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
  103. Multi-machine setup

  104. #".*."mode:"ruby".*. #"vi:"set"ft=ruby": Vagrant.configure("2")"do"|config| ""config.vm.provision""shell","inline:""/usr/bin/apt.get"update""""" ""config.vm.box"=""debian.7.1.0" "" ""config.vm.define""web","primary:"true"do"|web| """"""web.vm.hostname"=""web" """"""web.vm.network":private_network,"ip:""192.168.33.10" """"""web.vm.synced_folder""web/",""/var/www"""""""

    """"""web.vm.provision":puppet"do"|puppet| """"""""""puppet.manifests_path"=""./tools/puppet/manifests" """"""""""puppet.module_path"=""./tools/puppet/modules" """"""""""puppet.manifest_file""=""web.pp" """"""""""puppet.options"="['..verbose']"""" """"""end"""""" ""end ""config.vm.define""db""do"|db|" """"""db.vm.hostname"=""db" """"""db.vm.network":private_network,"ip:""192.168.33.11" """"""db.vm.provision":puppet"do"|puppet| """"""""""puppet.manifests_path"=""./tools/puppet/manifests" """"""""""puppet.module_path"=""./tools/puppet/modules" """"""""""puppet.manifest_file""=""db.pp" """"""""""puppet.options"="['..verbose'] """"""""""puppet.facter"="{ """""""""""""""root_password""=>""foo", """"""""""}"""""" """"""end"""""" ""end"" end
  105. $"vagrant"up Bringing"machine"'web'"up"with"'virtualbox'"provider... Bringing"machine"'db'"up"with"'virtualbox'"provider... [web]"Importing"base"box"'debian.7.1.0'... [web]"Matching"MAC"address"for"NAT"networking... [web]"Setting"the"name"of"the"VM... [web]"Clearing"any"previously"set"forwarded"ports... [web]"Creating"shared"folders"metadata... [web]"Clearing"any"previously"set"network"interfaces... [web]"Preparing"network"interfaces"based"on"configuration...

    [web]"Forwarding"ports... [web]".."22"=>"2222"(adapter"1) [web]"Booting"VM... [web]"Waiting"for"VM"to"boot."This"can"take"a"few"minutes. [web]"VM"booted"and"ready"for"use! [web]"Configuring"and"enabling"network"interfaces... [web]"Mounting"shared"folders... [web]".."/vagrant [web]".."/var/www [web]".."/tmp/vagrant.puppet/manifests [web]".."/tmp/vagrant.puppet/modules.0 [web]"Running"provisioner:"shell... [web]"Running:"inline"script [web]"Running"provisioner:"puppet... Running"Puppet"with"web.pp...
  106. [db]"Importing"base"box"'debian.7.1.0'... [db]"Matching"MAC"address"for"NAT"networking... [db]"Setting"the"name"of"the"VM... [db]"Clearing"any"previously"set"forwarded"ports... [db]"Fixed"port"collision"for"22"=>"2222."Now"on"port"2200. [db]"Creating"shared"folders"metadata... [db]"Clearing"any"previously"set"network"interfaces... [db]"Preparing"network"interfaces"based"on"configuration... [db]"Forwarding"ports... [db]".."22"=>"2200"(adapter"1)

    [db]"Booting"VM... [db]"Waiting"for"VM"to"boot."This"can"take"a"few"minutes. [db]"VM"booted"and"ready"for"use! [db]"Configuring"and"enabling"network"interfaces... [db]"Mounting"shared"folders... [db]".."/vagrant [db]".."/tmp/vagrant.puppet/manifests [db]".."/tmp/vagrant.puppet/modules.0 [db]"Running"provisioner:"shell... [db]"Running:"inline"script [db]"Running"provisioner:"puppet... Running"Puppet"with"db.pp...
  107. Control the machines

  108. 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
  109. And& on&that& bombshell&...

  110. vagrant'up #FTW

  111. h"ps://joind.in/9259 Please& give&me& feedback

  112. None