Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ITB2015 - Winning with Vagrant, Puppet and Chef

910 views

Published on

It works on your machine but not on a team mates? Coding on Windows but deploying to Linux? Or vice versa? Help remove the risk of deployment issues and problems sharing a codebase with your team members and use a project-wide development environment that is easy to manage and quick to install.

Published in: Technology
  • Be the first to comment

ITB2015 - Winning with Vagrant, Puppet and Chef

  1. 1. @coldfumonkeh Matt Gifford WINNING with VAGRANT, PUPPET and CHEF
  2. 2. Create and configure lightweight, reproducible, and portable development environments.
  3. 3. QUESTION
  4. 4. Environment per project Dev ~= Test ~= Staging ~= Production Easy to define & transport Easy to tear down Provisionable Versionable Shared across the team
  5. 5. ➜ ~ Usage: vagrant [options] <command> [<args>] -v, --version Print the version and exit. -h, --help Print this help. vagrant Common commands: box manages boxes: installation, removal, etc. connect connect to a remotely shared Vagrant environment destroy stops and deletes all traces of the vagrant machine global-status outputs status Vagrant environments for this user halt stops the vagrant machine help shows the help for a subcommand init initializes a new Vagrant environment by creating a Vagrantfile login log in to Vagrant Cloud package packages a running vagrant environment into a box plugin manages plugins: install, uninstall, update, etc. provision provisions the vagrant machine rdp connects to machine via RDP reload restarts vagrant machine, loads new Vagrantfile configuration resume resume a suspended vagrant machine share share your Vagrant environment with anyone in the world ssh connects to machine via SSH ssh-config outputs OpenSSH valid configuration to connect to the machine status outputs status of the vagrant machine suspend suspends the machine up starts and provisions the vagrant environment version prints current and latest Vagrant version
  6. 6. For help on any individual command run `vagrant COMMAND -h` Additional subcommands are available, but are either more advanced or not commonly used. To see all subcommands, run the command `vagrant list-commands`.
  7. 7. Generating a Vagrantfile
  8. 8. Select base box Choose virtualization provider Configure VM parameters Configure networking Tweak SSH settings Mount local folders Provision machine
  9. 9. ➜ ~ Usage: vagrant init [options] [name [url]] Options: -f, --force Overwrite existing Vagrantfile -m, --minimal Create minimal Vagrantfile (no help comments) --output FILE Output path for the box. '-' for stdout -h, --help Print this help vagrant init -h ➜ ~ 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.
  10. 10. 15 Vagrantfile # -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "base" end
  11. 11. ➜ ~ 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.
  12. 12. 17 Vagrantfile # -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "precise32" config.vm.box_url = "http://files.vagrantup.com/precise32.box" end
  13. 13. Boxes
  14. 14. http://vagrantbox.es
  15. 15. https://atlas.hashicorp.com/boxes/search
  16. 16. https://github.com/jedi4ever/veewee
  17. 17. https://packer.io
  18. 18. Box Management
  19. 19. ➜ ~ Usage: vagrant box <subcommand> [<args>] Available subcommands: add list outdated remove repackage update vagrant box
  20. 20. ➜ ~ ==> box: Adding box 'precise32' (v0) for provider: virtualbox box: Downloading: http://files.vagrantup.com/precise32.box box: Progress: 38% (Rate: 615k/s, Estimated time remaining: 0:04:25) ==> box: Successfully added box 'precise32' (v0) for 'virtualbox'! vagrant box add --provider virtualbox precise32 http:// files.vagrantup.com/precise32.box ➜ ~ vagrant box list atomia/windows-2012R2 (virtualbox, 0.2.0) precise32 (virtualbox, 0) ➜ ~ vagrant box list atomia/windows-2012R2 (virtualbox, 0.2.0)
  21. 21. box-disk1.vmdk box.ovf metadata.json Vagrantfile
  22. 22. 28 Up and Running (and destroying)
  23. 23. ➜ ~ 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: test_default_1430903546481_36514 ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 22 => 2222 (adapter 1) ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Connection timeout. Retrying... ==> default: Machine booted and ready! ==> default: Checking for guest additions in VM... default: The guest additions on this VM do not match the installed version of default: VirtualBox! In most cases this is fine, but in rare cases it can default: prevent things such as shared folders from working properly. If you see default: shared folder errors, please make sure the guest additions within the default: virtual machine match the version of VirtualBox you have installed on default: your host and reload your VM. default: default: Guest Additions Version: 4.2.0 default: VirtualBox Version: 4.3 ==> default: Mounting shared folders... default: /vagrant => /Users/monkehworks/my_project
  24. 24. ➜ ~ Bringing machine 'default' up with 'virtualbox' provider... ==> default: VirtualBox VM is already running. vagrant up ➜ ~ vagrant status Current machine states: default running (virtualbox) The VM is running. To stop this VM, you can run `vagrant halt` to shut it down forcefully, or you can run `vagrant suspend` to simply suspend the virtual machine. In either case, to restart it again, simply run `vagrant up`.
  25. 25. ➜ ~ ==> default: Saving VM state and suspending execution... vagrant suspend ➜ ~ vagrant status Current machine states: default saved (virtualbox) To resume this VM, simply run `vagrant up`.
  26. 26. ➜ ~ vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==> default: Resuming suspended VM... ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Connection refused. Retrying... ==> default: Machine booted and ready!
  27. 27. ➜ ~ ==> default: Attempting graceful shutdown of VM... vagrant halt ➜ ~ vagrant status Current machine states: default power (virtualbox) The VM is powered off. To restart the VM, simply run `vagrant up`.
  28. 28. ➜ ~ vagrant up Bringing machine 'default' up with 'virtualbox' provider... ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 22 => 2222 (adapter 1) ==> default: Booting VM... ==> default: Waiting for machine to boot. This may take a few minutes... default: SSH address: 127.0.0.1:2222 default: SSH username: vagrant default: SSH auth method: private key default: Warning: Connection timeout. Retrying... ==> default: Machine booted and ready! ==> default: Checking for guest additions in VM... default: The guest additions on this VM do not match the installed version of default: VirtualBox! In most cases this is fine, but in rare cases it can default: prevent things such as shared folders from working properly. If you see default: shared folder errors, please make sure the guest additions within the default: virtual machine match the version of VirtualBox you have installed on default: your host and reload your VM. default: default: Guest Additions Version: 4.2.0 default: VirtualBox Version: 4.3 ==> default: Mounting shared folders... default: /vagrant => /Users/monkehworks/my_project ==> default: Machine already provisioned. Run `vagrant provision` or use the `--provision` ==> default: to force provisioning. Provisioners marked to run always will still run.
  29. 29. ➜ ~ ==> default: Forcing shutdown of VM... ==> default: Destroying VM and associated drives... vagrant destroy ➜ ~ vagrant status Current machine states: default not created (virtualbox) default: Are you sure you want to destroy the 'default' VM? [y/N] y The environment has not yet been created. Run `vagrant up` to create the environment. If a machine is not created, only the default provider will be shown. So if a provider is not listed, then the machine is not created for that environment.
  30. 30. 36 Connections
  31. 31. ➜ ~ vagrant ssh Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.2.0-23-generic-pae i686) * Documentation: https://help.ubuntu.com/ New release '14.04.2 LTS' available. Run 'do-release-upgrade' to upgrade to it. Welcome to your Vagrant-built virtual machine. Last login: Wed May 6 13:56:45 2015 from 10.0.2.2 vagrant@precise32:~$ sudo su root@precise32:/home/vagrant#
  32. 32. root@precise32:/home/vagrant# cat .ssh/authorized_keys ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr +kz4TjGYe7gHzIw +niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYe t2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4p zC6kivAIhyfHilFR61RGL +GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm +R4LOzFUGaHqHDLKLX +FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
  33. 33. root@precise32:/home/vagrant# cat .ssh/authorized_keys ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr +kz4TjGYe7gHzIw +niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYe t2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4p zC6kivAIhyfHilFR61RGL +GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm +R4LOzFUGaHqHDLKLX +FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
  34. 34. ➜ ~ vagrant ssh-config Host default HostName 127.0.0.1 User vagrant Port 2222 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/monkehworks/.vagrant.d/insecure_private_key IdentitiesOnly yes LogLevel FATAL
  35. 35. ➜ ~ vagrant ssh-config Host default HostName 127.0.0.1 User vagrant Port 2222 UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentityFile /Users/monkehworks/.vagrant.d/insecure_private_key IdentitiesOnly yes LogLevel FATAL
  36. 36. ➜ ~ 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-----
  37. 37. Portability
  38. 38. By sharing your Vagrantfile you are essentially sharing your development environment.
  39. 39. 46 Infrastructure as Code
  40. 40. 47 Vagrantfile # -*- mode: ruby -*- # vi: set ft=ruby : VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "precise32" config.vm.box_url = "http://files.vagrantup.com/precise32.box" end
  41. 41. Networking
  42. 42. 49 config.vm.network :public_network Bridged Network
  43. 43. 50 config.vm.network :forwarded_port, guest: 80, host: 8080 Port Forwarding
  44. 44. 51 config.vm.network :private_network, ip: "192.168.10.10" Private IP Space
  45. 45. 52 Vagrant.configure(VAGRANTFILE_API_VERSION) 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 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: test_default_1431011744813_57334 ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat default: Adapter 2: hostonly ==> default: Forwarding ports... default: 22 => 2222 (adapter 1) ➜ ~ vagrant up
  46. 46. 53 Vagrant.configure(VAGRANTFILE_API_VERSION) 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 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: test_default_1431011744813_57334 ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat default: Adapter 2: hostonly ==> default: Forwarding ports... default: 22 => 2222 (adapter 1) ➜ ~ vagrant up
  47. 47. 54 Vagrant.configure(VAGRANTFILE_API_VERSION) 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 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: test_default_1431011744813_57334 ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 80 => 8080 (adapter 1) default: 22 => 2222 (adapter 1) ➜ ~ vagrant up
  48. 48. 55 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: test_default_1431011744813_57334 ==> default: Clearing any previously set network interfaces... ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat ==> default: Forwarding ports... default: 80 => 8080 (adapter 1) default: 22 => 2222 (adapter 1) ➜ ~ vagrant up Vagrant.configure(VAGRANTFILE_API_VERSION) 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
  49. 49. 56 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "precise32" config.vm.box_url = "http://files.vagrantup.com/precise32.box" config.vm.network :public_network end 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: test_default_1431012579630_44486 ==> default: Clearing any previously set network interfaces... ==> default: Available bridged network interfaces: 1) en1: Wi-Fi (AirPort) 2) en0: Ethernet 3) p2p0 default: What interface should the network bridge to? ➜ ~ vagrant up ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat default: Adapter 2: bridged ==> default: Forwarding ports... 1
  50. 50. 57 ➜ ~ 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: test_default_1431012579630_44486 ==> default: Clearing any previously set network interfaces... ==> default: Available bridged network interfaces: 1) en1: Wi-Fi (AirPort) 2) en0: Ethernet 3) p2p0 default: What interface should the network bridge to? ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat default: Adapter 2: bridged ==> default: Forwarding ports... 1 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "precise32" config.vm.box_url = "http://files.vagrantup.com/precise32.box" config.vm.network :public_network end
  51. 51. 58 ➜ ~ 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: test_default_1431012579630_44486 ==> default: Clearing any previously set network interfaces... ==> default: Available bridged network interfaces: 1) en1: Wi-Fi (AirPort) 2) en0: Ethernet 3) p2p0 default: What interface should the network bridge to? ==> default: Preparing network interfaces based on configuration... default: Adapter 1: nat default: Adapter 2: bridged ==> default: Forwarding ports... 1 Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "precise32" config.vm.box_url = "http://files.vagrantup.com/precise32.box" config.vm.network "public_network", :bridge => 'en1: Wi-‐Fi (AirPort)' end
  52. 52. Synced Folders
  53. 53. ==> default: Mounting shared folders... default: /vagrant => /Users/monkehworks/my_project Mount Management config.vm.synced_folder "htdocs/", "/var/www" ==> default: Mounting shared folders… default: /var/www => /Users/monkehworks/my_project/htdocs default: /vagrant => /Users/monkehworks/my_project
  54. 54. VM Properties
  55. 55. 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
  56. 56. Provisioning
  57. 57. Add specific software Create configuration files Execute commands Create users Manage services Automatically executed on vagrant up
  58. 58. Aim to have an exact (or as close as possible) copy of your production environment
  59. 59. Shell Ansible Chef Solo Chef Client Puppet Apply Puppet Agent
  60. 60. Shell Provisioning
  61. 61. config.vm.provision :shell, :inline => "mount ‐t tmpfs ‐o size=50m,mode=0777 tmpfs /vagrant/ app/cache"
  62. 62. # -*- mode: ruby -*- # vi: set ft=ruby : $script = <<SCRIPT echo I am provisioning... date > /etc/vagrant_provisioned_at SCRIPT VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "precise32" config.vm.box_url = "http://files.vagrantup.com/precise32.box" config.vm.provision :shell, :inline $script end
  63. 63. config.vm.provision "shell", path: "script.sh" config.vm.provision "shell", path: "https://example.com/provisioner.sh" External Scripts
  64. 64. 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 and more… Chef & Puppet
  65. 65. Chef Puppet Modules Cookbooks Modules Actions Recipes Manifests Language Ruby extended with DSL DSL Running order Sequential “Random” Approach Define actions Define state Programming style Procedural “OO-esque”
  66. 66. An Intro to Chef
  67. 67. 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 Using Chef Solo
  68. 68. Vagrantfile 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
  69. 69. cookbook ├── README.md ├── attributes ├── definitions ├── files │ └── default ├── libraries ├── metadata.rb ├── providers ├── recipes │ └── default.rb ├── resources └── templates └── default
  70. 70. 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' MySQL Attributes
  71. 71. ... 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 ... MySQL Server Recipe
  72. 72. [client] host user = localhost = 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 MySQL Template
  73. 73. Cron Directory Execute File Git Group Link Log Package Service Template User and more... Typical Chef resources
  74. 74. Cooking for yourself
  75. 75. 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
  76. 76. 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
  77. 77. Vagrantfile VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "precise32" config.vm.box_url = “http://files.vagrantup.com/precise32.box" config.vm.synced_folder "htdocs/", "/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
  78. 78. ➜ ~ vagrant up ... ==> default: Mounting shared folders… default: /var/www => /Users/monkehworks/my_project/htdocs default: /vagrant => /Users/monkehworks/my_project ==> default: /tmp/vagrant-chef-1/chef-solo-1/cookbooks ==> default: Running provisioner: chef_solo… Generating chef JSON and uploading… Running chef-solo… ...
  79. 79. An Intro to Puppet
  80. 80. Download modules - https://forge.puppetlabs.com Configure in Vagrantfile: - puppet.module_path - puppet.manifests_path - puppet.manifest_file Provisioning flow happens in the main manifest Configure attributes with puppet.facter Using Puppet Apply
  81. 81. Vagrantfile 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 init.pp include mysql::server class { '::mysql::server' :root_password => 'foo' }
  82. 82. module ├── README.md ├── files ├── lib ├── metadata.json ├── spec ├── manifests │ └── init.pp │ └── params.pp ├── resources └── templates └── tests
  83. 83. 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
  84. 84. 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 { ...
  85. 85. [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'] ‐%> MySQL Template
  86. 86. Computer Cron Exec File Filebucket Group Host Interface Package Service Sshkey User and more… Typical Puppet resources
  87. 87. Pulling your own strings
  88. 88. 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
  89. 89. ./tools/puppet/manifests/init.pp 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"], }
  90. 90. Vagrantfile VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "precise32" config.vm.box_url = “http://files.vagrantup.com/precise32.box" config.vm.synced_folder "htdocs/", "/var/www" config.vm.provision :puppet do |puppet| puppet.manifests_path = "./tools/puppet/manifests" puppet.module_path = "./tools/puppet/modules" puppet.manifest_file = “init.pp" puppet.facter = { “root_password” => “foo”, } puppet.options = ['--verbose'] end end
  91. 91. (when machine is running) ➜ ~ vagrant provision
  92. 92. Problems with Provisioning
  93. 93. Provisioning is often slow Quality of public cookbooks/manifests Support on cookbooks/manifests Writing it yourself can be difficult Distribution restrictions
  94. 94. ➜ ~ vagrant package
  95. 95. 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
  96. 96. Multi-Machine Setup
  97. 97. VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) 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 "htdocs/", "/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
  98. 98. VAGRANTFILE_API_VERSION = "2" Vagrant.configure(VAGRANTFILE_API_VERSION) 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 "htdocs/", "/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
  99. 99. ➜ ~ vagrant up ➜ ~ vagrant destroy ➜ ~ vagrant ssh ➜ ~ vagrant up web ➜ ~ vagrant ssh web ➜ ~ vagrant destroy web ➜ ~ vagrant up db ➜ ~ vagrant ssh db ➜ ~ vagrant destroy db
  100. 100. ColdFusion and Vagrant
  101. 101. https://github.com/lewg/cfenv-chef https://github.com/davejlong/vagrant-boxes https://github.com/mikesprague/vagrant-lemtl https://github.com/bdcravens/railo-vagrant https://github.com/gratzc/it-works-on-my-machine-chef-vagrant
  102. 102. #WINNING

×