itb2015 - winning with vagrant, puppet and chef
TRANSCRIPT
Environment per project Dev ~= Test ~= Staging ~= Production Easy to define & transport Easy to tear down Provisionable Versionable Shared across the team
➜ ~
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
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`.
Select base box Choose virtualization provider Configure VM parameters Configure networking Tweak SSH settings Mount local folders Provision machine
➜ ~
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 nowready to `vagrant up` your first virtual environment! Please readthe comments in the Vagrantfile as well as documentation on`vagrantup.com` for more information on using Vagrant.
15
Vagrantfile
# -*- mode: ruby -*-# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "base" end
➜ ~ vagrant init precise32 http://files.vagrantup.com/precise32.box
A `Vagrantfile` has been placed in this directory. You are nowready to `vagrant up` your first virtual environment! Please readthe comments in the Vagrantfile as well as documentation on`vagrantup.com` for more information on using Vagrant.
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
➜ ~
Usage: vagrant box <subcommand> [<args>]
Available subcommands: add list outdated remove repackage update
vagrant box
➜ ~
==> 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)
➜ ~ 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
➜ ~
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` toshut it down forcefully, or you can run `vagrant suspend` to simplysuspend the virtual machine. In either case, to restart it again,simply run `vagrant up`.
➜ ~
==> 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`.
➜ ~ 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!
➜ ~
==> 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`.
➜ ~ 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.
➜ ~
==> 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` tocreate the environment. If a machine is not created, only thedefault provider will be shown. So if a provider is not listed,then the machine is not created for that environment.
➜ ~ vagrant sshWelcome 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.2vagrant@precise32:~$ sudo su
root@precise32:/home/vagrant#
root@precise32:/home/vagrant# cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
root@precise32:/home/vagrant# cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
➜ ~ 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
➜ ~ 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
➜ ~ cat ~/.vagrant.d/insecure_private_key-----BEGIN RSA PRIVATE KEY-----MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKdELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzfTK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnKiqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4AsClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iPcXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7RkEjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pNCAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZGYEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWCP9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDFllYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJkda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH+vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQNE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s=-----END RSA PRIVATE KEY-----
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
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
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
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
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
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: Ethernet3) 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
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: Ethernet3) 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
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: Ethernet3) 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
==> 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
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 = trueend
Add specific software Create configuration files Execute commands Create users Manage services Automatically executed on vagrant up
config.vm.provision :shell, :inline => "mount ‐t tmpfs ‐o size=50m,mode=0777 tmpfs /vagrant/ app/cache"
# -*- mode: ruby -*-# vi: set ft=ruby :
$script = <<SCRIPTecho I am provisioning...date > /etc/vagrant_provisioned_atSCRIPT
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
config.vm.provision "shell", path: "script.sh"
config.vm.provision "shell", path: "https://example.com/provisioner.sh"
External Scripts
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
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”
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
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
cookbook├── README.md├── attributes├── definitions├── files│ └── default├── libraries├── metadata.rb├── providers├── recipes│ └── default.rb├── resources└── templates└── default
default['mysql']['port'] = 3306default['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
...group 'mysql' do action :createend
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 endend...
MySQL Server Recipe
[client]host user = localhost
= debian-sys-maintpassword = <%= node['mysql']['server_debian_password'] %>socket = <%= node['mysql']['socket'] %>
[mysql_upgrade]host = localhostuser = debian‐sys-maintpassword = <%= node['mysql']['server_debian_password'] %>socket = <%= node['mysql']['socket'] %>basedir = /usr
MySQL Template
Cron Directory Execute File Git Group Link
Log Package Service Template User and more...
Typical Chef resources
execute 'update apt' do command "apt‐get update" action :runend
package 'mysql-server' do action :install notifies :start, 'service[mysql]', :immediatelyend
package 'apache2' do action :install notifies :start, 'service[apache2]', :delayedend
package 'php5' do action :install notifies :reload, 'service[apache2]', :delayedend
./tools/chef/cookbooks/project/recipes/default.rb
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 :enableend
service 'apache2' do service_name 'apache2' supports :status => true, :restart => true, :reload => true action :enableend
./tools/chef/cookbooks/project/recipes/default.rb
VagrantfileVAGRANTFILE_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
➜ ~ 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…...
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
Vagrantfileconfig.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.ppinclude mysql::server
class { '::mysql::server' :root_password => 'foo' }
module├── README.md├── files├── lib├── metadata.json├── spec├── manifests│ └── init.pp│ └── params.pp├── resources└── templates└── tests
MySQL Paramsclass 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
MySQL server manifestclass 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 {...
[client]user=roothost=localhost<% unless scope.lookupvar('mysql::server::root_password') == 'UNSET' ‐%>password='<%= scope.lookupvar('mysql::server::root_password') %>'<% end ‐%>socket=<%= @options['client']['socket'] ‐%>
MySQL Template
Computer Cron Exec File Filebucket Group Host Interface
Package Service Sshkey User and more…
Typical Puppet resources
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
./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"],}
VagrantfileVAGRANTFILE_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
Provisioning is often slow Quality of public cookbooks/manifests Support on cookbooks/manifests Writing it yourself can be difficult Distribution restrictions
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
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 end
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 end
➜ ~ vagrant up
➜ ~ vagrant destroy
➜ ~ vagrant ssh
➜ ~ vagrant up web
➜ ~ vagrant ssh web
➜ ~ vagrant destroy web
➜ ~ vagrant up db
➜ ~ vagrant ssh db
➜ ~ vagrant destroy db
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