2. What is Vagrant?
● Syntactic sugar around VMs
○ Virtualbox
○ VMWare
○ LXC
○ AWS
○ Rackspace
○ etc, etc, etc
3. What is Vagrant?
● Syntactic sugar around provisioning
○ Chef
○ Puppet
○ CFEngine
○ Scripts (bash, etc)
○ etc, etc, etc
4. What is Vagrant?
● Five commands
○ vagrant up
○ vagrant provision
○ vagrant ssh
○ vagrant suspend
○ vagrant destroy
● Actually 18 commands (v1.5)
○ You really only use the 5 above.
5. It’s just Ruby
● Runs on Windows, Linux, OSX
● Use all the programming constructs
○ loops
○ variables
○ etc
● Check the environment
○ Great for working with Jenkins
● Bring in gems
6. It’s just a configuration file
● You’re building a configuration file
○ Actions don’t happen immediately
● The Vagrant engine is intuitive
○ (usually)
7. require 'vagrant-vbguest'
max_memory = 4 * 1024 # This is in megabytes
Vagrant.configure("2") do |config|
config.vm.provider :virtualbox do |vb, override|
override.vm.box = "precise64"
override.vm.box_url = "http://some.place.com/some/path.box"
vb.customize ["modifyvm", :id, "--memory", max_memory]
end
end
8. require ‘vagrant-lxc’
max_memory = 4 * 1024 # This is in megabytes
Vagrant.configure("2") do |config|
config.vm.provider :lxc do |lxc, override|
override.vm.box = "precise64"
override.vm.box_url = "http://some.otherplace.com/some/path.box"
lxc.customize 'cgroup.memory.limit_in_bytes', "#{max_memory}M"
end
end
9. require 'vagrant-vbguest'
require ‘vagrant-lxc’
max_memory = 4 * 1024 # This is in megabytes
Vagrant.configure("2") do |config|
config.vm.provider :virtualbox do |vb, override|
….
end
config.vm.provider :lxc do |lxc, override|
….
end
end
10. Provider details
● Provider is specified in “vagrant up”
○ Other commands detect the provider
● There are dozens of providers
○ Virtualbox, VMWare, LXC, Docker
○ AWS, Joyent, Rackspace, DigitalOcean
○ OpenStack, Parallels
● Writing your own isn’t all that hard
○ Prior art is very helpful, as is mailing list and IRC
11. Shared Folders
● By default, the folder with the Vagrantfile is
shared into /vagrant
○ Can be changed
● Can add more shared folders
○ The provisioners already do this
● For cloud VMs, “shared” means “rsync’ed on
demand”.
12. Vagrant.configure("2") do |config|
chefdir = ‘.’
config.vm.provision :chef_solo do |chef|
chef.roles_path = “#{chefdir}/roles”
chef.run_list.clear
chef.add_role "container"
end
end
13. Vagrant.configure("2") do |config|
chefdir = ‘devops/chef’
config.vm.provision :chef_solo do |chef|
chef.roles_path = “#{chefdir}/roles”
chef.run_list.clear
chef.add_role "container"
end
end
15. Provisioner details
● The order provisioners are declared matters.
○ If one fails, the remainder will not run.
● Can mix-and-match
○ Normally one chef/puppet/etc and several shell
16. Multiple VMs
● Can launch 1-N VMs
○ Each VM must have a unique name
● Each VM can have a different:
○ provider (one and only one)
○ set of provisioners
○ configuration, including:
■ network interface
17. Vagrant.configure("2") do |config|
config.vm.define “web” do |web|
web.vm.provision ‘shell’, inline: “echo “web” > /etc/vagrant_purpose”
web.vm.provider :chef-solo do |chef|
end
end
config.vm.define “database” do |database|
database.vm.provision ‘shell’, inline: “echo “database” > /etc/vagrant_purpose”
database.vm.provider :puppet do |puppet|
end
end
end
18. Vagrant.configure("2") do |config|
config.vm.provider :virtualbox do |vb, override|
...
end
(‘web’, ‘database’).each do |name|
config.vm.define name do |machine|
machine.vm.provision ‘shell’, inline: “echo “#{name}” > /etc/vagrant_purpose”
end
end
end
19. So what?
● This isn’t just another cool tool.
● Sometimes, all you need is simpler controls.
○ Everything has always been possible, just most
things are too expensive to build.
20. Clone production
● Dev and QA should be clones of Prod
○ Prod doesn’t run on a single server
○ So, why does QA and Dev?
21. Setup load-testing
● Use a cloud provider (AWS, etc)
● A Vagrantfile that has:
○ Your production structure
○ Your load-testing systems (Tsung, JMeter, etc)
● Running a load test is now just:
○ vagrant up
○ vagrant ssh load1 -c “/vagrant/bin/run_load_test.sh”
22. Jenkins and Testing
● Testing should be in a clone of Production
○ The best clone is what you’ll build Production from
● Jenkins can integrate with Vagrant
○ vagrant up
○ vagrant ssh -c “/vagrant/bin/run_tests.sh”
■ This will return the exit code properly
23. Vagrant.configure("2") do |config|
# Configure the AWS provider here
NUM = # Figure out how many instances to run
(1 .. NUM).each do |index|
config.vm.define “test#{index}” do |test|
test.vm.provision ‘shell’, inline: “echo “test#{index}” > /etc/vagrant_purpose”
test.vm.provider :aws do |aws|
aws.tags = { ‘Name’ => “#{aws.tags[‘Name’]}-test#{index}” }
end
end
end
end
24. Automate Golden Images
$ vagrant up --provider=aws
$ ec2-create-image
`cat .vagrant/machines/default/aws/id`
--name “my_new_ami”
$ vagrant destroy -f
25. Putting it all together (A Crazy Idea)
● Let developers manage server changes
○ Provisioners for a project are checked into that
project’s repository
○ Developers can make changes
○ Vagrant lets them test out changes in a clone of
production
○ Devops participates in code reviews (as needed)
■ Devops has veto over changes to devops/
directory and code.
26. Putting it all together (A Crazy Idea)
● Devops is no longer responsible for:
○ Server changes
● Devops IS responsible for:
○ Validating proposed server changes
○ Ensuring the pipeline for server changes
○ Training the developers to own their server changes
● Job changes
○ Build the engine instead of pulling the rickshaw
27. Community is key
● https://github.com/rails/rails-dev-box
● https://github.com/jpettersson/vagrant-rails-
project-box
○ Same thing, but with Chef
● http://manuel.manuelles.
nl/blog/2013/07/23/developing-ruby-on-rails-
on-windows/
○ Same thing, but on Windows