Vagrant Life Cycle

Vagrant is a command line tool for building and managing virtual machine environments with a focus on automation through flexible configuration.

These are just some notes on how to get up and running, and working with the Vagrant life-cycle.

Starting Out

Having installed Vagrant and Virtual Box (On Ubuntu: ‘apt install vagrant virtualbox’), the first thing required is a Vagrantfile.

This file defines the required end state of your virtual envinronment. Here is a simple example:

Vagrant.configure("2") do |config|

  config.vm.box = "centos/7"
  config.vm.hostname = "vm2"
  config.vm.network "public_network"
  
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.cpus = 2
  end
end

‘config.vm.box’ defines the image you wish to create a VM from. Many community provided images are available at https://app.vagrantup.com/boxes. This example uses a CentOS image.

Create a directory and save the above as ‘Vagrantfile’. Inside that directory, running ‘vagrant up’ will retrieve the named image, create and configure an instance as specified:

rich@thevmserver:~/vagrant$ vagrant up
Bringing machine 'vm1' up with 'virtualbox' provider...
==> vm1: Importing base box 'centos/7'...
==> vm1: Checking if box 'centos/7' is up to date...
==> vm1: Running 'pre-boot' VM customizations...
==> vm1: Booting VM...
==> vm1: Waiting for machine to boot. This may take a few minutes...
<-- snipped some lines for brevity -->
==> vm1: Machine booted and ready!
==> vm1: Setting hostname...
==> vm1: Configuring and enabling network interfaces...
vm1: SSH address: 127.0.0.1:2222
vm1: SSH username: vagrant
vm1: SSH auth method: private key
==> vm1: Rsyncing folder: /home/rich/vagrant/ => /vagrant
==> vm1: Running provisioner: file...

At this point, a fully functional VM is up and running, which can be accessed using ‘vagrant ssh’ (or externally via SSH if a public network was configured):

rich@thevmserver:~/vagrant$ vagrant ssh vm1
[vagrant@vm1 ~]$ hostname
vm1

Life Cycle

Some of the more useful life-cycle commands:

  1. up: creates VM instances as defined in config, and starts them
  2. halt: stops VM instances
  3. destroy: stops and deletes VM instances

Multiple VMs

Vagrant is also capable of managing multiple VMs in a single config. To do this use ‘config.vm.define’ for each instance:

Vagrant.configure("2") do |config|

  config.vm.define "vm1" do |vm1|  
    vm1.vm.box = "centos/7"
    vm1.vm.hostname = "vm1"
  end

  config.vm.define "vm2" do |vm2|
    vm2.vm.box = "centos/7"
    vm2.vm.hostname = "vm2"
  end
  
  config.vm.network "public_network"
  
  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
    vb.cpus = 2
  end
end

Note that any config in the outer scope (e.g. config.vm.network) is applied to all VM instances.

SSH

By default Vagrant will generate an SSH key for each VM, and use that to replace the insecure key most images are built with. To use a pre-defined key generated through ssh-keygen, update the vagrant file with:

config.ssh.insert_key = false
config.ssh.private_key_path = ["~/.ssh/id_rsa", "~/.vagrant.d/insecure_private_key"]
config.vm.provision "file", source: "~/.ssh/id_rsa.pub", destination: "~/.ssh/authorized_keys"

Change ~/.ssh/id_rsa and ~/.ssh/id_rsa.pub to point at where your keys live.