Magneticore

Development, Operations and Design

  • Articles
  • Resume
  • About Me
  • Contact
  • DevOps
  • Featured
  • Astronomy
  • Portfolio
  • UI/UX
You are here: Home / Articles / VM boxes with Bento and Vagrant

VM boxes with Bento and Vagrant

February 4, 2015 by Jorge Morales

Bento

When you have the need to create VM boxes that can run in multiple environments Packer is an excellent choice.

Out of the box Packer comes with support to build images for Amazon EC2, DigitalOcean, Google Compute Engine, QEMU, VirtualBox, VMware, and more.

Support for more platforms is on the way, and anyone can add new platforms via plugins.

For a local development environment we can leverage the advantages of using Vagrant to run VMs and test or develop right in a clean environment without inadvertently introducing settings or configurations of our host machine.

This allows to level the conditions of the development, staging, QA and production environments.

In this way we would avoid circumstances like:

I don’t know what happened. It ran fine in my machine.

Before we continue you will need these requirements:

  • Virtualbox or VMware Fusion.
  • Vagrant
  • Git

Bento

First let me introduce Bento https://github.com/chef/bento

Bento is a project that encapsulates Packer templates for building Vagrant baseboxes. To use it we need to install Packer.

Installing Packer

To install Packer download the corresponding package from: https://www.packer.io/downloads.html

Extract the package and then add the folder to your PATH.

For example:

You could add it to your ~/.profile file.

export PATH$PATH:/path/to/docker

Then to test in the terminal run:

~: docker
usage: packer [--version] [--help] <command> [<args>]

Available commands are:
 build build image(s) from template
 fix fixes templates from old versions of packer
 inspect see components of a template
 push push template files to a Packer build service
 validate check that a template is valid
 version Prints the Packer version

If you get the quick help of Docker then you’re on! Otherwise check the directory again and don’t forget to restart your terminal session.

Cloning Bento

Let’s create a directory where we will host the code:

~: cd ~
~: mkdir baseboxes
~: cd baseboxes

 

The next step is to clone bento’s repository:

~/baseboxes: git clone https://github.com/opscode/bento.git
Cloning into 'bento'...
remote: Counting objects: 3129, done.
remote: Compressing objects: 100% (7/7), done.
remote: Total 3129 (delta 3), reused 2 (delta 1)
Receiving objects: 100% (3129/3129), 652.65 KiB | 0 bytes/s, done.
Resolving deltas: 100% (1986/1986), done.
Checking connectivity... done.

Great!  git clone created a directory called bento inside baseboxes. Let’s take a look into it:

~/baseboxes: ls bento/packer/
centos-5.11-i386.json     freebsd-10.1-amd64.json   oracle-6.6-x86_64.json    solaris-10.5-x86.json
centos-5.11-x86_64.json   freebsd-10.1-i386.json    packer_cache              solaris-11-x86.json
centos-6.6-i386.json      freebsd-9.3-amd64.json    rhel-5.11-i386.json       ubuntu-10.04-amd64.json
centos-6.6-x86_64.json    freebsd-9.3-i386.json     rhel-5.11-x86_64.json     ubuntu-10.04-i386.json
centos-7.0-x86_64.json    http                      rhel-6.6-i386.json        ubuntu-12.04-amd64.json
debian-6.0.10-amd64.json  macosx-10.7.json          rhel-6.6-x86_64.json      ubuntu-12.04-i386.json
debian-6.0.10-i386.json   macosx-10.8.json          rhel-7.0-x86_64.json      ubuntu-14.04-amd64.json
debian-7.8-amd64.json     macosx-10.9.json          scripts                   ubuntu-14.04-i386.json
debian-7.8-i386.json      omnios-r151010j.json      sles-11-sp2-i386.json     ubuntu-14.10-amd64.json
fedora-20-i386.json       opensuse-13.2-i386.json   sles-11-sp2-x86_64.json   ubuntu-14.10-i386.json
fedora-20-x86_64.json     opensuse-13.2-x86_64.json sles-11-sp3-i386.json     vagrantfile_templates
fedora-21-i386.json       oracle-5.11-i386.json     sles-11-sp3-x86_64.json
fedora-21-x86_64.json     oracle-5.11-x86_64.json   sles-12-x86_64.json
floppy                    oracle-6.6-i386.json      solaris-10.11-x86.json

We have baseboxes definitions for a number of Operating Systems that we can build with Bento. From there it is easy to create custom versions if necessary. Let’s take a look at one of them:

{
  "builders": [
    {
      "boot_command": [
        "<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/centos-6.6/ks.cfg<enter><wait>"
      ],
      "boot_wait": "10s",
      "disk_size": 40960,
      "guest_additions_path": "VBoxGuestAdditions_{{.Version}}.iso",
      "guest_os_type": "RedHat_64",
      "http_directory": "http",
      "iso_checksum": "08be09fd7276822bd3468af8f96198279ffc41f0",
      "iso_checksum_type": "sha1",
      "iso_url": "{{user `mirror`}}/6.6/isos/x86_64/CentOS-6.6-x86_64-bin-DVD1.iso",
      "output_directory": "packer-centos-6.6-x86_64-virtualbox",
      "shutdown_command": "echo 'vagrant'|sudo -S /sbin/halt -h -p",
      "ssh_password": "vagrant",
      "ssh_port": 22,
      "ssh_username": "vagrant",
      "ssh_wait_timeout": "10000s",
      "type": "virtualbox-iso",
      "vboxmanage": [
        [
          "modifyvm",
          "{{.Name}}",
          "--memory",
          "480"
        ],
        [
          "modifyvm",
          "{{.Name}}",
          "--cpus",
          "1"
        ]
      ],
      "virtualbox_version_file": ".vbox_version",
      "vm_name": "packer-centos-6.6-x86_64"
    },
    {
      "boot_command": [
        "<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/centos-6.6/ks.cfg<enter><wait>"
      ],
      "boot_wait": "10s",
      "disk_size": 40960,
      "guest_os_type": "centos-64",
      "http_directory": "http",
      "iso_checksum": "08be09fd7276822bd3468af8f96198279ffc41f0",
      "iso_checksum_type": "sha1",
      "iso_url": "{{user `mirror`}}/6.6/isos/x86_64/CentOS-6.6-x86_64-bin-DVD1.iso",
      "output_directory": "packer-centos-6.6-x86_64-vmware",
      "shutdown_command": "echo 'vagrant'|sudo -S /sbin/halt -h -p",
      "ssh_password": "vagrant",
      "ssh_port": 22,
      "ssh_username": "vagrant",
      "ssh_wait_timeout": "10000s",
      "tools_upload_flavor": "linux",
      "type": "vmware-iso",
      "vm_name": "packer-centos-6.6-x86_64",
      "vmx_data": {
        "cpuid.coresPerSocket": "1",
        "memsize": "480",
        "numvcpus": "1"
      }
    },
    {
      "boot_command": [
        "<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/centos-6.6/ks.cfg<enter><wait>"
      ],
      "boot_wait": "10s",
      "disk_size": 40960,
      "parallels_tools_flavor": "lin",
      "guest_os_type": "centos",
      "http_directory": "http",
      "iso_checksum": "08be09fd7276822bd3468af8f96198279ffc41f0",
      "iso_checksum_type": "sha1",
      "iso_url": "{{user `mirror`}}/6.6/isos/x86_64/CentOS-6.6-x86_64-bin-DVD1.iso",
      "output_directory": "packer-centos-6.6-x86_64-parallels",
      "shutdown_command": "echo 'vagrant'|sudo -S /sbin/halt -h -p",
      "ssh_password": "vagrant",
      "ssh_port": 22,
      "ssh_username": "vagrant",
      "ssh_wait_timeout": "10000s",
      "type": "parallels-iso",
      "prlctl": [
        [
          "set",
          "{{.Name}}",
          "--memsize",
          "480"
        ],
        [
          "set",
          "{{.Name}}",
          "--cpus",
          "1"
        ]
      ],
      "prlctl_version_file": ".prlctl_version",
      "vm_name": "packer-centos-6.6-x86_64"
    }

  ],
  "post-processors": [
    {
      "output": "../builds/{{.Provider}}/opscode_centos-6.6_chef-{{user `chef_version`}}.box",
      "type": "vagrant"
    }
  ],
  "provisioners": [
    {
      "environment_vars": [
        "CHEF_VERSION={{user `chef_version`}}"
      ],
      "execute_command": "echo 'vagrant' | {{.Vars}} sudo -S -E bash '{{.Path}}'",
      "scripts": [
        "scripts/centos/fix-slow-dns.sh",
        "scripts/common/sshd.sh",
        "scripts/common/vagrant.sh",
        "scripts/common/vmtools.sh",
        "scripts/common/chef.sh",
        "scripts/centos/cleanup.sh",
        "scripts/common/minimize.sh"
      ],
      "type": "shell"
    }
  ],
  "variables": {
    "chef_version": "provisionerless",
    "mirror": "http://mirrors.kernel.org/centos"
  }
}

From the previous snippet we can appreciate the amount of parameters that we can fine tune according to our needs. For example we can change the number of CPUs, the memory and disk size.

There are also some parameters specific to the provisioners (VirtualBox or VMware).

Building a basebox

Let’s change directory to:

cd bento/packer/

If we only have VMware or Virtualbox installed we can tell packer to build only a box to run in such an environment like so:

~/baseboxes/bento/packer: packer build -only=vmware-iso centos-6.6-x86_64.json

or:

~/baseboxes/bento/packer: packer build -only=virtualbox-iso centos-6.6-x86_64.json

Time to go for a coffee… Anyone?

After running the corresponding command bento-packer will:

  • Download the ISO file of the selected OS
  • Create a Virtual Machine
  • VNC into it and start an unattended installation
  • In my case it installs VMware tools since I’m using fusion
  • Clean all the temporary files and cache packages
  • Compress the resulting vm disk

Finally we see the following in the command line:

Build 'vmware-iso' finished.

==> Builds finished. The artifacts of successful builds are:
--> vmware-iso: 'vmware' provider box: ../builds/vmware/opscode_centos-6.6_chef-provisionerless.box

~/baseboxes/bento/packer: cd ../builds/vmware/

 

Vagrant

Let’s list the installed boxes in vagrant. In my case:

~/baseboxes/bento/builds/vmware: vagrant box list
chef/centos-6.5            (vmware_desktop, 1.0.0)
chef/ubuntu-12.04          (vmware_desktop, 1.0.0)
opscode-centos-6.5         (vmware_desktop, 0)
opscode-ubuntu-12.04       (vmware_desktop, 0)
phusion/ubuntu-14.04-amd64 (vmware_fusion, 2014.04.30)

Add

To use the newly created basebox we need to add it to vagrant:

~/baseboxes/bento/builds/vmware: 
vagrant box add --name opscode-centos-6.6 opscode_centos-6.6_chef-provisionerless.box
==> box: Adding box 'opscode-centos-6.6' (v0) for provider:
    box: Downloading: file:///Users/jorgemorales/baseboxes/bento/builds/vmware/opscode_centos-6.6_chef-provisionerless.box
==> box: Successfully added box 'opscode-centos-6.6' (v0) for 'vmware_desktop'!

Let’s list again to check that the box has been added:

~: vagrant box list
chef/centos-6.5            (vmware_desktop, 1.0.0)
chef/ubuntu-12.04          (vmware_desktop, 1.0.0)
opscode-centos-6.5         (vmware_desktop, 0)
opscode-centos-6.6         (vmware_desktop, 0)
opscode-ubuntu-12.04       (vmware_desktop, 0)
phusion/ubuntu-14.04-amd64 (vmware_fusion, 2014.04.30)

Test

Now let’s test the box. I will create a directory newproject and then initialize our new box:

~: mkdir newproject
~: cd newproject
~/newproject: vagrant init opscode-centos-6.6
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

Run

Looking good. Why don’t we start the new machine.

~/newproject: vagrant up
Bringing machine 'default' up with 'vmware_fusion' provider...
==> default: Cloning VMware VM: 'opscode-centos-6.6'. This can take some time...
==> default: Verifying vmnet devices are healthy...
==> default: Preparing network adapters...
==> default: Starting the VMware VM...
==> default: Waiting for the VM to finish booting...
==> default: The machine is booted and ready!
==> default: Forwarding ports...
    default: -- 22 => 2222
==> default: Configuring network adapters within the VM...
==> default: Waiting for HGFS kernel module to load...
==> default: Enabling and configuring shared folders...
    default: -- /Users/jorgemorales/repos/newproject: /vagrant

Excellent! The box is up and running ready to take our code or test whatever we need.

Stop

For now let’s stop the machine and remove the vm file.

~/newproject: vagrant halt
==> default: Attempting graceful shutdown of VM...

~/newproject: vagrant destroy
    default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Deleting the VM...

Remove

If necessary we can remove the box from our vagrant list:

~: vagrant box remove opscode-centos-6.6
Removing box 'opscode-centos-6.6' (v0) with provider 'vmware_desktop'...

~: vagrant box list
chef/centos-6.5            (vmware_desktop, 1.0.0)
chef/ubuntu-12.04          (vmware_desktop, 1.0.0)
opscode-centos-6.5         (vmware_desktop, 0)
opscode-ubuntu-12.04       (vmware_desktop, 0)
phusion/ubuntu-14.04-amd64 (vmware_fusion, 2014.04.30)

And that’s it! Enjoy.

What are you waiting for? It’s time to start coding something awesome!

Filed Under: Articles, DevOps

About the author

My name is Jorge Morales and I am an Electronics Engineer by training, a technology starter by choice and Open Source fan.
My curiosity led me to get involved in many areas from Instrumentation, Support, Operations to Development.
Often as a member of multidisciplinary teams, sometimes leading or working as a senior individual contributor.

I spend my time remixing the web Open Source style!
UNAM and Ottawa Startup Weekend Alumni, Co-founder of @YourBookBuddy.
I lead the implementation on Coral platform and production systems at CoralCEA.

Recent Articles

  • Kano Computer for Kids based on Raspberry pi
  • Welcome Home App and Meteor part 2
  • Welcome Home App and Meteor
  • Are we alone in the universe?
  • A new car UI
I'm currently looking for new opportunities. Are you interested, let's chat!

Work with Jorge Now

Previous role

Project Lead at CoralCEA where I led the implementation on Coral platform and Coral's production systems.

 

I’m also in here…

  • Email
  • GitHub
  • LinkedIn
  • Twitter

Copyright © 2025 · Magneticore · My online Resume

Copyright © 2025 · Log in