Intro to Vagrant

Daniel Farrell
Red Hat SDN Team

VERY QUICK: INTRO TO ME

Daniel Farrell
Software Engineer, Red Hat SDN Team

VERY QUICK: INTRO TO ME

OpenDaylight Contributor

VERY QUICK: INTRO TO ME

OpenDaylight Integration Committer


Very Quick: Intro to ME

Other code!
 

VERY QUICK: INTRO TO ME

Robots!
 

VERY QUICK: INTRO TO ME

(Craft) Beer!

VERY QUICK: INTRO TO ME

Biking!

VERY QUICK: INTRO TO ME

SCUBA!

Overview

Overview

Describe a VM in a Vagrantfile

Overview

Configure the VM using Provisioners
(Shell, Chef, Puppet, Ansible, Docker...)

Overview

Stand up the VM using a Provider
(VirtualBox, OpenStack, Digital Ocean...)

OVERVIEW

Share your Vagrantfile

OVERVIEW

Profit!

Why You'll love Vagrant

Dev Edition

Why Devs Love Vagrant

Isolation of dependencies and configuration

WHY DEVS LOVE VAGRANT

Project has a Vagrantfile?
`vagrant up`!

WHY DEVS LOVE VAGRANT

Never again: "I can't get your software running. Help!"

WHY DEVS LOVE VAGRANT

OS agnostic
(even your Mac-using coworkers can do it!)
And, uh, that other OS...

Why Devs love Vagrant

Vagrantfile can be version controlled

Why you'll love Vagrant

Ops Edition

Why Ops love Vagrant

Puppet? Chef? Shell scripts?
All of the above and more!

Why Ops Love Vagrant

Deploy same config locally or remotely
`vagrant up --provider=digital_ocean`

dEtails!

Basic Example

Basic example

Create a Vagrantfile

[~]$ mkdir foss_rocks
[~]$ cd foss_rocks
[~/foss_rocks]$ vagrant init -m chef/fedora-20
[~/foss_rocks]$ ls
Vagrantfile

BASIC EXAMPLE

It's so simple!
[~/foss_rocks]$ cat Vagrantfile
Vagrant.configure(2) do |config|
  config.vm.box = "chef/fedora-20"
end

Basic Example

Boot the VM
[~/foss_rocks]$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Checking if box 'chef/fedora-20' is up to date...
==> default: Preparing network interfaces based on configuration...
==> default: Booting VM...
==> default: Machine booted and ready!
==> default: Mounting shared folders...
    default: /vagrant => /home/daniel/foss_rocks

Basic Example

Connect to the VM
[~/foss_rocks]$ vagrant ssh
Last login: Fri Dec 20 18:02:34 2013 from 10.0.2.2
[vagrant@localhost ~]$

Basic Example

It works!
[vagrant@localhost ~]$ ping 8.8.8.8 -c 1
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=63 time=13.7 ms
[vagrant@localhost ~]$ cat /etc/issue
Fedora release 20 (Heisenbug)

BASIC EXAMPLE

Vagrantfile dir is hard linked to /vagrant (default)
[vagrant@localhost ~]$ ls /vagrant/
Vagrantfile

Provisioners

PROVISIONERS

They configure the VM

PROVISIONERS

Common ones: Shell, Ansible, Chef, Puppet, Salt, Docker

SHELL PROVISIONER

Shell Provisioner

Add shell provisioning to basic example
Vagrant.configure(2) do |config|
  config.vm.box = "chef/fedora-20"
  config.vm.provision "shell", inline: "yum install -y nmap"
end

SHELL PROVISIONER

Basic example VM is already up

[~/foss_rocks]$ vagrant status
Current machine states:

default                   running (virtualbox)

SHELL PROVISIONER

Just re-provision it

[~/foss_rocks]$ vagrant provision
==> default: Running provisioner: shell...
    default: Running: inline script
[snip]
==> default: Installed:
==> default:   nmap.x86_64 2:6.45-1.fc20         

SHELL PROVISIONER

NMap is now installed
[~/foss_rocks]$ vagrant ssh
Last login: Fri Feb  6 16:03:05 2015 from 10.0.2.2
[vagrant@localhost ~]$ command -v nmap
/usr/bin/nmap

Puppet PROVISIONER

PUPPET PROVISIONER

Add Puppet provisioning to basic example
Vagrant.configure(2) do |config|
  config.vm.box = "chef/fedora-20"

  # Install Puppet
  config.vm.provision "shell", inline: "yum install -y puppet"

  # Install OpenDaylight using its Puppet module
  config.vm.provision "puppet" do |puppet|
    # Mostly using default settings
    # The module path tells Puppet where to find required modules
    puppet.module_path = ["modules"]
  end
end

PUPPET PROVISIONER

Note the "Convention over Configuration"
  config.vm.provision "puppet" do |puppet|
    # Mostly using default settings
    # The module path tells Puppet where to find required modules
    puppet.module_path = ["modules"]
  end

PUPPET PROVISIONER

Convention for file layout

[~/foss_rocks]$ tree
.
├── manifests
│   └── default.pp
└── Vagrantfile

PUPPET PROVISIONER

The Puppet manifest is trivial
[~/foss_rocks]$ cat manifests/default.pp
include ::opendaylight

PUPPET PROVISIONER

Puppet-specific stuff to manage modules
[~/foss_rocks]$ tree
.
├── Gemfile
├── manifests
│   └── default.pp
├── Puppetfile
└── Vagrantfile

PUPPET PROVISIONER

Gemfile is for sharing gem config via Bundler
[~/foss_rocks]$ cat Gemfile
source "https://rubygems.org"

gem 'puppet'
gem 'librarian-puppet'  # Used for managing Puppet mods

PUPPET PROVISIONER

Puppetfile describes how to find ODL mod
(only needed b/c it's not on the Forge)
[~/foss_rocks]$ cat Puppetfile
#!/usr/bin/env ruby

forge "https://forgeapi.puppetlabs.com"

mod 'dfarrell07-opendaylight',
  :git => 'git://github.com/dfarrell07/puppet-opendaylight.git'

PUPPET PROVISIONER

Install all required gems
[~/foss_rocks]$ bundle install
[snip]
Your bundle is complete!

PUPPET PROVISIONER

Install OpenDaylight Puppet module
[~/foss_rocks]$ ls
Gemfile  manifests  Puppetfile  Vagrantfile
[~/foss_rocks]$ librarian-puppet install
[~/foss_rocks]$ tree -L 2
.
├── Gemfile
├── manifests
│   └── default.pp
├── modules
│   ├── opendaylight
│   └── stdlib
├── Puppetfile
├── Puppetfile.lock
└── Vagrantfile

PUPPET PROVISIONER

For a change, let's destroy the VM
[~/foss_rocks]$ vagrant destroy -f
==> default: Forcing shutdown of VM...
==> default: Destroying VM and associated drives...
==> default: Running cleanup tasks for 'shell' provisioner...
[~/foss_rocks]$ vagrant status
Current machine states:

default                   not created (virtualbox)

PUPPET PROVISIONER

Now rebuild it, using Puppet to install ODL
[~/foss_rocks]$ vagrant up
==> default: Running provisioner: shell...
==> default: Running provisioner: puppet...
==> default: Running Puppet with default.pp...
==> default: Notice: Finished catalog run in 59.59 seconds

PUPPET PROVISIONER

Connect and show that ODL is working
[~/foss_rocks]$ vagrant ssh
Last login: Fri Dec 20 18:02:34 2013 from 10.0.2.2
[vagrant@localhost ~]$ sudo systemctl is-active opendaylight
active

Providers

PROVIDERS

Used to manage different types of machines

PROVIDERS

Common ones: VBox, AWS, Digital Ocean, VMWare

VBox Provider

VBOX PROVIDER

Default used by Vagrant

VBOX PROVIDER

You'll have to install VBox separately

VBOX PROVIDER

Configuring VM resources
# Configure VM RAM and CPU
config.vm.provider "virtualbox" do |vbox|
  vbox.memory = 2048
  vbox.cpus = 4
end

VBOX PROVIDER

Note VBox process when running locally
[~/foss_rocks]$ vagrant status
Current machine states:

default                   running (virtualbox)
[~/foss_rocks]$ pgrep VBoxHeadless
5822

Digital Ocean Provider

DIGITAL OCEAN PROVIDER

Stand up VMs on DO's infra

DIGITAL OCEAN PROVIDER

Consistent interface
[~/foss_rocks]$ vagrant up --provider=digital_ocean
Bringing machine 'default' up with 'digital_ocean' provider...

DIGITAL OCEAN PROVIDER

Example configuration
  config.vm.provider :digital_ocean do |provider, override|
    override.ssh.private_key_path = "~/.ssh/id_rsa"
    override.vm.box = "digital_ocean"
    override.vm.box_url = "https://github.com/smdahlen/vagrant-digitalocean/raw/master/box/digital_ocean.box"
    provider.token = "<token here>"
    provider.image = "centos-7-0-x64"
    provider.region = "nyc3"
    provider.size = "512mb"
  end

DIGITAL OCEAN PROVIDER

And it's up!

DIGITAL OCEAN PROVIDER

Same interface to connect
[~/foss_rocks]$ vagrant ssh
[root@default ~]# ping -c 1 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=58 time=1.86 ms

MULTI-MACHINE

Multi-machine

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.define "cent7_puppet" do |cent7_puppet|
    # Configure CentOS 7 box using Puppet
         to install ODL
  end
  config.vm.define "fed20_puppet" do |fed20_puppet|
    # Configure Fedora 20 box using Puppet
         to install ODL
  end
  config.vm.define "fed20_rpm" do |fed20_rpm|
    # Configure Fedora 20 box using RPM to install ODL
  end
  config.vm.define "cent7_rpm" do |cent7_rpm|
    # Configure CentOS 7 box using RPM to install ODL
  end

MULTI-MACHINE

  config.vm.define "cent7_puppet" do |cent7_puppet|
    # Build Vagrant box based on CentOS 7
    cent7_puppet.vm.box = "chef/centos-7.0"

    # Add Puppet repo and install Puppet
    cent7_puppet.vm.provision "shell", inline: "rpm -ivh http://yum.puppetlabs.com/puppetlabs-release-el-7.noarch.rpm"
    cent7_puppet.vm.provision "shell", inline: "yum install -y puppet"

    # Snip: Puppet provisioning step
  end
  config.vm.define "fed20_puppet" do |fed20_puppet|
    # Build Vagrant box based on Fedora 20
    fed20_puppet.vm.box = "chef/fedora-20"

    # Install Puppet
    fed20_puppet.vm.provision "shell", inline: "yum install -y puppet"

    # Snip: Puppet provisioning step
  end

MULTI-MACHINE

[~/vagrant_opendaylight]$ vagrant status
Current machine states:

cent7_puppet              not created (virtualbox)
fed20_puppet              poweroff (virtualbox)

Other Resources

OTHER RESOURCES

The main Vagrant docs are *great*
^^Likely all you need

Contact

Daniel Farrell
Twitter (optimal):

Others:
dfarrell@redhat.com
dfarrell07 on IRC, GitHub

Introduction to Vagrant

By Daniel Farrell

Introduction to Vagrant

Talk given at the NCSU LUG's 2015 FOSS Fair

  • 1,615
Loading comments...

More from Daniel Farrell