Short introduction to Packer and Vagrant

October 31, 2021 

This article is a short introduction to Packer and Vagrant - tools that we often recommend to our customers but which may be a bit hard to understand if you have no previous expose to them.

Packer

Packer is used to “create identical machine images for multiple platforms from a single source configuration”. Packer works in a very simple fashion:

  1. It reads its configuration file
  2. It launches a virtual machine based on the “base box” you’ve defined. The base box would be a “vanilla” Linux distribution such as Ubuntu 20.04.
  3. It runs the provisioning scripts you’ve written on the base box (via SSH)
  4. It removes deployment-specific things (e.g. SSH host keys)
  5. It shuts down the VM
  6. It creates a VM image out of base box + your changes

After this you can distribute the base box to people and they will have an identical system at their disposal. If you need to modify the image you can just change the provisioning scripts and/or the base image and rebuild. The configuration file can and should be stored in version control repository.

Packer is often used to modify VM images before distributing them to the general public. For example Cloud images in AWS or Azure are probably mostly built with Packer.

Vagrant

Vagrant works very similarly to Packer, but it is aimed at developers, as evidenced by its slogan: “Development Environments Made Easy”. Vagrant works like this:

  1. It reads its configuration file
  2. It launches a virtual machine based on the “base box” you’ve defined. The base box would be a “vanilla” Linux distribution such as Ubuntu 20.04. The base box gets downloaded automatically.
  3. Optionally it mounts the directory (or multiple) from the host system to the guest system. Often the source code directory which contains the Vagrant configuration file is mounted.
  4. It runs the provisioning scripts you’ve written on the base box (via SSH)
  5. Optionally it sets up port forwarding etc. to allow access to services inside the guest

You can think of Vagrant as a very convenient wrapper around your virtualization software (Virtualbox, Hyper-V, Libvirt, AWS EC2, Docker, etc). Multiple virtualization backends can be supported with the same configuration file.

From developer perspective use of Vagrant is easy. To create the virtual environment - or start it if it has been created already:

vagrant up

To shut it down:

vagrant halt

To destroy the environment:

vagrant destroy

To rebuild the environment:

vagrant up

To rerun provisioning scripts (e.g. to update configuration inside the virtual environment):

vagrant provision

To connect to a Linux instance via SSH:

vagrant ssh

To connect to a Windows instance via RDP:

vagrant rdp

Vagrant is very useful in creating reproducible, fully self-contained development environments, especially in cross-platform environments where developers use a mixture of Linux, Windows and MacOS. It also works very well as a tool for developing infrastructure as code (e.g. Puppet or Ansible) aimed at managing servers and desktops. With the Docker provider you can even use Docker as the backend to improve your Docker container development workflow.

You might want to consider pure Docker instead of Vagrant if your use-case is simple, such as "we just want developers to be able to build our software without having to worry about installing its dependencies locally". If you want developers to actually have a consistent development environment as opposed to build environment then full virtualization with Vagrant may be a better choice.

Samuli Seppänen
Samuli Seppänen
Author archive
menucross-circle