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.
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!
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
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.