config managament for development environments ii
DESCRIPTION
Talk for the London Ruby User Group about using configuration management tools to manage development environments. Lots of Vagrant and Chef code examples.TRANSCRIPT
gareth rushgrove | morethanseven.net
Configuration Managementfor Development Environments
LRUG 8th August 2011
http://www.flickr.com/photos/36144637@N00/159627088/
Gareth Rushgrove
gareth rushgrove | morethanseven.net
Blog at morethanseven.net
gareth rushgrove | morethanseven.net
Curate devopsweekly.com
gareth rushgrove | morethanseven.net
http://www.flickr.com/photos/iancarroll/5027441664gareth rushgrove | morethanseven.net
Problems
http://www.flickr.com/photos/34652102@N04/5059217055gareth rushgrove | morethanseven.net
1. Not all developers want to be sysadmins
http://www.flickr.com/photos/34652102@N04/5059824808gareth rushgrove | morethanseven.net
2. New team members getting started time
http://www.flickr.com/photos/biggreymare
3. Running a full set of services locally
gareth rushgrove | morethanseven.net
4. Works on my machine
gareth rushgrove | morethanseven.net
⚡ brew info mysqlmysql 5.5.14
$ aptitude show mysql-serverPackage: mysql-serverState: not installedVersion: 5.1.41-3ubuntu12.10
Homebrew is great but...
gareth rushgrove | morethanseven.net
What’s a few versions between friends?
gareth rushgrove | morethanseven.net
- An ORDER BY clause was bound to the incorrect substatement when used in UNION context.
- A NOT IN predicate with a subquery containing a HAVING clause could retrieve too many rows, when the subquery itself returned NULL.
- MIN(year_col) could return an incorrect result in some cases.
23 releases and 21 months in-between 5.1.41 and 5.5.14. Here’s some fixed bugs:
And lots more
Spot the cross platform bug (not the security flaw)
gareth rushgrove | morethanseven.net
⚡ ./server.rb &⚡ curl "http://127.0.0.1:8181/?query=Bob"⚡ curl "http://127.0.0.1:8181/?query=bob"⚡ lsBob⚡ cat BobHello bob
On our Mac
gareth rushgrove | morethanseven.net
$ ./server.rb &$ curl "http://127.0.0.1:8181/?query=Bob"$ curl "http://127.0.0.1:8181/?query=bob"$ lsBob bob$ cat BobHello Bob$ cat bobHello bob
On Linux
gareth rushgrove | morethanseven.net
gareth rushgrove | morethanseven.net http://www.flickr.com/photos/34652102@N04/5059208501
Solutions
http://www.flickr.com/photos/dawilson/2598713027
Virtualisation
gareth rushgrove | morethanseven.net
VirtualBox
gareth rushgrove | morethanseven.net
VMware
gareth rushgrove | morethanseven.net
Virtualisation needs powerful hardware
gareth rushgrove | morethanseven.net http://www.flickr.com/photos/martinoc/477335951
gareth rushgrove | morethanseven.net http://www.flickr.com/photos/peteradams/2272928740
What about editing code?
http://www.flickr.com/photos/34652102@N04/5059846582
Shared Folders or NFS
gareth rushgrove | morethanseven.net
Doubledown
Vim
gareth rushgrove | morethanseven.net
Vagrantup.com
gareth rushgrove | morethanseven.net
What is Vagrant?
gareth rushgrove | morethanseven.net
- Automated virtual machine creation using Oracle’s VirtualBox- Automated provisioning of virtual environments using Chef or Puppet- Full SSH access to created environments- Assign a static IP to your VM, accessible from your machine- Forward ports to the host machine- Shared folders allows you to continue using your own editor- Package environments into distributable boxes- Completely tear down environment when you’re done- Easily rebuild a complete environment with a single command
http://www.flickr.com/photos/dawilson/2793319903
Base boxes
gareth rushgrove | morethanseven.net
VeeWee
gareth rushgrove | morethanseven.net
gareth rushgrove | morethanseven.net
Community boxes
⚡ gem install vagrant⚡ vagrant box add lucid32 http://.../lucid32.box⚡ vagrant init⚡ vagrant up
Vagrant up
gareth rushgrove | morethanseven.net
⚡ lsVagrantfile⚡ vagrant up⚡ vagrant ssh⚡ vagrant reload⚡ vagrant halt⚡ vagrant destroy
Vagrant command line
gareth rushgrove | morethanseven.net
⚡ vagrant ssh-configHost default HostName 127.0.0.1 User vagrant Port 2222 IdentityFile /Users/.../vagrant-0.8.2/keys/vagrant ...
Export SSH configuration
gareth rushgrove | morethanseven.net
Vagrant::Config.run do |config| config.vm.box = "lucid32"end
Vagrantfile
gareth rushgrove | morethanseven.net
Vagrant::Config.run do |config| config.vm.forward_port("web", 80, 8080) config.vm.forward_port("ftp", 21, 4567) config.vm.forward_port("ssh", 22, 2222, :auto => true)end
Port forwarding
gareth rushgrove | morethanseven.net
Vagrant::Config.run do |config| config.vm.share_folder("folder", "/guest", "../host")end
Shared folders
gareth rushgrove | morethanseven.net
Vagrant::Config.run do |config| config.vm.define :web do |web_config| web_config.vm.box = "web" web_config.vm.forward_port("http", 80, 8080) end
config.vm.define :db do |db_config| db_config.vm.box = "db" db_config.vm.forward_port("db", 3306, 3306) endend
Multiple VMs in one file
gareth rushgrove | morethanseven.net
Vagrant::Config.run do |config| config.vm.boot_mode = :gui config.ssh.forward_agent = true config.vm.customize do |vm| vm.memory_size = 512 endend
Lots more options
gareth rushgrove | morethanseven.net
Puppet
gareth rushgrove | morethanseven.net
Vagrant provisioning with Puppet
gareth rushgrove | morethanseven.net
Vagrant::Config.run do |config| config.vm.provision :puppet do |puppet| puppet.manifests_path = "puppetmanifests" puppet.manifest_file = "newbox.pp" endend
Chef
gareth rushgrove | morethanseven.net
Vagrant provisioning with Chef
gareth rushgrove | morethanseven.net
Vagrant::Config.run do |config| config.vm.provision :chef_solo do |chef| chef.add_recipe = "garethr" chef.cookbooks_path = “cookbooks” endend
Specifying Chef roles
gareth rushgrove | morethanseven.net
Vagrant::Config.run do |config| config.vm.provision :chef_solo do |chef| chef.roles_path = "roles" chef.add_role("vm") endend
Vagrant::Config.run do |config| config.vm.provision :chef_solo do |chef| chef.recipe_url = "http://github.com/cookbooks.tar.gz" chef.add_recipe "garethr" chef.cookbooks_path = [:vm, "cookbooks"] chef.json.merge!({ :garethr => { :ohmyzsh => "https://github.com/.../oh-my-zsh.git", :dotvim => "https://github.com/garethr/dotvim.git" }}) endend
gareth rushgrove | morethanseven.net
Remote file
http://www.flickr.com/photos/s3a/4710416678
Plugins
gareth rushgrove | morethanseven.net
- Vagrant Hosts - https://github.com/dwt/vagrant-hosts- Sahara - https://github.com/jedi4ever/sahara- Vagrantboxes - https://github.com/garethr/ruby-vagrantboxes
http://www.flickr.com/photos/crustyscumbrothersontour/2674351601
Local configuration management
gareth rushgrove | morethanseven.net
gareth rushgrove | morethanseven.net
Real world example
gareth rushgrove | morethanseven.netgareth rushgrove | morethanseven.net
- I want my development environment everywhere- I don’t want a wiki page of instructions- I don’t want to have to manually install everything- I don’t want to care about destroying a virtual machine- So I have a simple Chef cookbook to bootstrap my machines
⚡ cd /m/somefolder⚡ tree├── Vagrantfile└── cookbooks └── garethr ├── attributes │ └── default.rb ├── files │ └── default │ └── zshrc └── recipes └── default.rb
Chef cookbook layout
gareth rushgrove | morethanseven.net
Packages I like
gareth rushgrove | morethanseven.net
%w{zsh wget curl lynxgit-core ack-grep vim-noxdvtm build-essential tree}.each do |pkg| package pkg do action :install endend
My shell configs
gareth rushgrove | morethanseven.net
git "/home/vagrant/.oh-my-zsh" do repository node[:garethr][:ohmyzsh] action :checkout user "vagrant" group "vagrant"end
cookbook_file "/home/vagrant/.zshrc" do source "zshrc" owner "vagrant" group "vagrant"end
Attributes
gareth rushgrove | morethanseven.net
default[:garethr][:dotvim] = "https://github.com/carlhuda/janus.git"
default[:garethr][:ohmyzsh] = "https://github.com/robbyrussell/oh-my-zsh.git"
My Vim configs
gareth rushgrove | morethanseven.net
git "/home/vagrant/.vim" do repository node[:garethr][:dotvim] action :checkout user "vagrant"end
execute "build janus" do command "rake" user "vagrant" cwd "/home/vagrant/.vim" environment ({'HOME' => '/home/vagrant'}) creates "/home/vagrant/.vimrc"end
Testing with ChefSpec
gareth rushgrove | morethanseven.net
require "chefspec"
describe "garethr" do before(:all) do @chef_run = ChefSpec::ChefRunner.new @chef_run.converge "garethr" end
it "should install zsh" do @chef_run.should install_package "zsh" endend
gareth rushgrove | morethanseven.net
Awesome things I ignored
gareth rushgrove | morethanseven.netgareth rushgrove | morethanseven.net
- The Chef Server- Roles and Environments- Knife and Shef- Splitting the one file into multiple cookbooks- Managing running services- Simplifying cookbooks by creating system packages- Supporting different operating systems- The Chef architecture- Testing with Cucumber-Chef
gareth rushgrove | morethanseven.net
Conclusions
gareth rushgrove | morethanseven.netgareth rushgrove | morethanseven.net
- Using Virtualisation catches bugs early- Using Vagrant makes using virtual machines pleasurable- Storing configuration as code makes it shareable- Able to apply development best practice to dev environments
More information
gareth rushgrove | morethanseven.net
- IRC - #vagrant on Freenode- Github Issues - https://github.com/mitchellh/vagrant/issues- Google Groups - http://groups.google.com/group/vagrant-up
Questions?
gareth rushgrove | morethanseven.net http://flickr.com/photos/psd/102332391/