search by tags

for the user

adventures into the land of the command line

the awesomeness of vagrant

so when i started using linux, i didnt understand anything. i still dont understand a lot… but one of the things i have come to understand is that computers are complicated because of people. everyone thinks in different ways and as a result, people do things in different ways. we code in a particular way, we structure our files and directories in a particular way, some of us are messy, some of us are neat, blah blah blah.

because of this i think, there are a myriad of ways in which you can try to simplify the way you work with computers when confronted with this unavoidable human element. the principle is somewhat like python’s virtualenv, in that you can work in your own contained environment without muddying anyone else’s work. you can build it, break it, and rebuild it at your own pleasure. this could also be done with git branches, or with docker containers, i guess there’s a bunch of things you could use.

vagrant is just one example. it’s a command line tool that helps you spin up entire virtual machines on your local computer (with the help of a hypervisor like virtualbox or parallels or vmware). it also helps you destroy them whenever you want. its great and i love it.

so how can we use it? first you need to make sure you have a hypervisor installed. i like to use virtualbox, but vagrant supports heaps

we’d want to start by installing it on our machine. im using a mac, so here’s how to install it on a mac. go here, and download the .dmg file, then install it like you would any other app on a mac. this will create a /Vagrant directory that you can put your projects into.

we’d then want to continue by finding a machine image. vagrant is one of the products offered by hashicorp, and hashicorp have a bunch of images you can search thru here

i use virtualbox, and i want a centos6 image with an ansible provisioner. with luck, there’s one in hashicorp!

https://atlas.hashicorp.com/maurofelipe/boxes/centOS-6.7-x86_64

the page has info about the project source, as well as the vagrant commands to run to pull it down and start using it. awesome

initialise the image from the hashicorp atlas

$ vagrant init maurofelipe/centOS-6.7-x86_64

on a mac, this will download a .box file into

~/.vagrant.d/boxes

it will also put a basic Vagrantfile into the directory you ran this command from. the Vagrantfile is the config for the vm which you can add things to. here’s an exmaple of one i use, which incorporates an ansible provisioner

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|

  config.vm.provider "virtualbox" do |v|
    v.memory = 512
    v.cpus = 1
    v.gui = false
  end

  config.vm.define "myapp" do |myapp|
    myapp.vm.box = "maurofelipe/centOS-6.7-x86_64"
    myapp.vm.network "forwarded_port", guest: 80, host: 8080, auto_correct: true
    myapp.vm.network "private_network", ip: "192.168.50.8"
    myapp.vm.hostname = "myapp"
    myapp.vm.synced_folder "/users/sebastian/Vagrant/myapp/", "/opt/myapp/"
  end

  config.ssh.username = "vagrant"
  config.ssh.pty = true

  config.vm.provision "ansible" do |ansible|
    ansible.playbook = "../ansible_home/site.yml"
    ansible.inventory_path = "../ansible_home/inventories/dev/hosts"
    ansible.limit = "myapp"
  end

end

this allows me to get the ansible binary on the vagrant machine to build the vm from playbooks on my host, pretty nifty

you might see a synced folder towards the middle of the config. this allows you to specify which folders on your local machine can be accessed by the vagrant machine. it’s really useful for when you want to use a text editor like sublime to edit your code on you local machine, and have the changes reflected inside the virtual machine.

some useful commands for boxes

$ vagrant box add ADDRESS
$ vagrant box remove NAME
$ vagrant box list

launch the vm

$ vagrant up

launch the vm with a specific hypervisor

$ vagrant up --provider virtualbox

launch the vm and provision with a provisioner like ansible or salt

$ vagrant up --provision

re-run the provisioner, so that you don’t need to reboot the guest to save time

$ vagrant provision

log in to the vm

$ vagrant ssh

teardown a vm

$ vagrant suspend (pause)
$ vagrant halt (power off)
$ vagrant destroy (delete)

reset or reload the vm with new configs

$ vagrant reload

reset or reload the vm with new configs and re-provision

$ vagrant reload --provision

those are most of the commands i need to use it and it makes making things so easy.

what if you want to setup a test where you need more than one vm, say for instance to test mysql database replication. here’s a config for a multi-vm setup:

# -*- mode: ruby -*-
# vi: set ft=ruby :

Vagrant.configure(2) do |config|

  config.vm.provider "virtualbox" do |v|
    v.memory = 512
    v.cpus = 1
    v.gui = false
  end

  config.vm.define "db1" do |db1|
    db1.vm.box = "dhoppe/ubuntu-14.04.5-amd64-nocm"
    db1.vm.network "forwarded_port", guest: 3306, host: 3306, auto_correct: true
    db1.vm.network "private_network", ip: "192.168.50.4"
    db1.vm.hostname = "mysql1"
    db1.vm.synced_folder "~/Vagrant/dbs/", "/vagrant/dbs/",
        owner: "mysql", group: "mysql"
  end

  config.vm.define "db2" do |db2|
    db2.vm.box = "dhoppe/ubuntu-14.04.5-amd64-nocm"
    db2.vm.network "forwarded_port", guest: 3306, host: 3307, auto_correct: true
    db2.vm.network "private_network", ip: "192.168.50.5"
    db2.vm.hostname = "mysql2"
    db2.vm.synced_folder "~/Vagrant/dbs/", "/vagrant/dbs/",
        owner: "mysql", group: "mysql"
  end

  config.ssh.username = "vagrant"
  config.ssh.pty = true

end

the only difference when there’s more than one vm is you need to specify the one you want to ssh to

$ vagrant ssh db1
$ vagrant ssh db2

i have read that you can use vagrant to provision aws ec2 instances which sounds really cool, although i haven’t looked into it more. maybe in the future.