Virtualized Development Environments with

Vagrant and Puppet

Created by Lyubomir Popov / @lpopov

Reasons to virtualize

  • Multiple projects depending on different kinds of software
  • Multiple projects depending on different versions of the same software
  • Decreases setup time for a new developer joining the project
  • Increases chances of successful deployments by mirroring production environment
  • Reuse Puppet recipes in production and development environments
  • 'Works on my machine' syndrome

What is Vagrant?

  • Command line tool written by Mitchell Hashimoto
  • Automates VM creation with Virtualbox, VMware, AWS
  • Integrates with provisioning tools like shell scripts, Chef and Puppet
  • Runs on Linux, Mac OS X and Windows

Why use Vagrant?

  • You can create VMs quickly and easily
  • You can reproduce exactly the same environment on different systems
  • You need to keep only a small number of text files, to recreate an environment

Vagrant commands


$ vagrant init user/box   # Create Vagrantfile for specified base box
$ vagrant up              # Create a VM if needed and boot
$ vagrant reload          # After every change to Vagrantfile
$ vagrant halt            # Turns off the VM
$ vagrant destroy         # Deletes the VM
$ vagrant suspend         # Suspends the VM
$ vagrant resume          # Resumes the VM
$ vagrant ssh             # Log in using ssh
$ vagrant status          # Status of the VM
                    

Getting up and running

Install Vagrant and Virtualbox (www.vagrantup.com and www.virtualbox.org)


$ vagrant init hashicorp/precise32
$ vagrant up 
$ vagrant ssh
                    

Vagrantfile

  • Network configuration
  • Port forwarding
  • Shared folders
  • VM configuration (RAM, CPU, Threads)
  • Provisioner setup

Vagrantfile

Created with 'vagrant init hashicorp/precise32'


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "hashicorp/precise32"
end
                        

Vagrantfile

Adding networking


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "hashicorp/precise32"
  config.vm.network "private_network", ip: "10.0.1.10"
end
                        

Vagrantfile

Port forwarding


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "hashicorp/precise32"
  config.vm.network "private_network", ip: "10.0.1.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080
end
                        

Vagrantfile

Shared folders


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "hashicorp/precise32"
  config.vm.network "private_network", ip: "10.0.1.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.synced_folder "./", "/vagrant"
end
                        

Vagrantfile

VM configuration (RAM, CPU, Network)


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "hashicorp/precise32"
  config.vm.network "private_network", ip: "10.0.1.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.synced_folder "./", "/vagrant"
  config.vm.provider :virtualbox do |vb|
    # vb.customize ["startvm", :id, "--type", "gui"]
    vb.customize ["modifyvm", :id, "--memory", "512"]
    vb.customize ["modifyvm", :id, "--cpus", "1"]
    vb.customize ["modifyvm", :id, "--hwvirtex", "on"]
    vb.customize ["modifyvm", :id, "--audio", "none"]
    vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
    vb.customize ["modifyvm", :id, "--nictype2", "virtio"]
  end
end
                        

Vagrantfile

Provisioner setup


VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "hashicorp/precise32"
  config.vm.network "private_network", ip: "10.0.1.10"
  config.vm.network "forwarded_port", guest: 80, host: 8080
  config.vm.synced_folder "./", "/vagrant"
  config.vm.provider :virtualbox do |vb|
    # vb.customize ["startvm", :id, "--type", "gui"]
    vb.customize ["modifyvm", :id, "--memory", "512"]
    vb.customize ["modifyvm", :id, "--cpus", "1"]
    vb.customize ["modifyvm", :id, "--hwvirtex", "on"]
    vb.customize ["modifyvm", :id, "--audio", "none"]
    vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
    vb.customize ["modifyvm", :id, "--nictype2", "virtio"]
  end

  config.vm.provision "puppet" do |puppet|
    puppet.manifests_path = "puppet/manifests"
    puppet.module_path = "puppet/modules"
    puppet.manifest_file  = "site.pp"
  end
end
                        

What is Puppet?

  • One of the market leaders in configuration management
  • Configuration management system that allows you to define the state of your IT infrastructure, then automatically enforces the correct state
  • Works as well on a single server, as on thousands of physical and virtual machines
  • Automates tasks that sysadmins often do manually
  • Ensures consistency, reliability and stability

Example


class php {
  package { ['php5',
             'php5-cli',
             'libapache2-mod-php5',
             'php5-mysql',
             'php5-sqlite',
             'php5-tidy',
             'php5-xdebug']:
    ensure => present;
  }
}
                    

File structure


$ tree --prune puppet
puppet              
├── manifests    
│   └── site.pp  
└── modules      
    ├── apache
    │   ├── files
    │   │   └── vagrant-vhost.conf
    │   └── manifests
    │       └── init.pp
    ├── mysql
    │   └── manifests
    │       └── init.pp
    └── php
        ├── files
        │   └── php.ini
        └── manifests
            └── init.pp

10 directories, 6 files
                    

Demo time

Recap

  • Download and install Vagrant and Virtualbox
  • Clone repository
  • $ vagrant up

Links (Part 1)

Links (Part 2)

Questions?

Thank you