In this post I will cover how to create an Arista Vagrant box for use with the vagrant-libvirt provider. This post assumes a working installation of Vagrant with the vagrant-libvirt plugin already installed. You can follow this post to get the vagrant-libvirt plugin installed.

For reference the following software will be used in this post.

  • EOS - vEOS-lab-4.18.1F.vmdk
  • EOS Boot image - Aboot-veos-8.0.0.iso
  • Vagrant - Vagrant 1.9.6
  • vagrant-libvirt - 0.4.0


Arista does not provide a Vagrant Libvirt box like they do for the Virtualbox provider, so we will need to download the vmdk from the Arista software download page. Note: An account is required to download the software but, its free to register and no support contract is required.

Once you have logged in download vEOS-lab-4.18.1F.vmdk and Aboot-veos-8.0.0.iso.


Create and change into directory for veos files. I like to keep my custom vagrant boxes under ~/vagrant/boxes/.

mkdir -p ~/vagrant/boxes/arista/veos-4-18-1f-libvirt
cd ~/vagrant/boxes/arista/veos-4-18-1f-libvirt

Copy the veos files downloaded earlier to the veos-4-18-1f-libvirt directory.

cp ~/Downloads/{vEOS-lab-4.18.1F.vmdk,Aboot-veos-8.0.0.iso} .

The good folks who maintain the vagrant-libvirt plugin have a script can be used to convert qcow2 images to a vagrant box. Download the libvirt convertsion script.

curl -O

We will first need to build the Arista veos VM to apply a bootstrap config to allow Vagrant to login and manage the box. The easiest way I have found is the create a definition file to describe the VM's configuration. Download this veos.xml file and be sure to update the paths to where you have stored your box.qcow2 (created in a later step) and Aboot-veos-8.0.0.iso files.

curl -O curl -O

For reference the file looks like this.

<domain type='kvm'>
<memory unit='KiB'>2097152</memory>
<currentMemory unit='KiB'>2097152</currentMemory>
<vcpu placement='static'>2</vcpu>
  <type arch='x86_64' machine='pc-i440fx-1.5'>hvm</type>
  <boot dev='cdrom'/>
  <boot dev='hd'/>
<clock offset='utc'/>
  <disk type='file' device='disk'>
    <driver name='qemu' type='qcow2'/>
    <source file='/home/bradmin/vagrant/boxes/arista/veos-4-18-1f-libvirt/box.qcow2'/>
    <target dev='hda' bus='ide'/>
    <alias name='ide0-0-0'/>
    <address type='drive' controller='0' bus='0' target='0' unit='0'/>
  <disk type='file' device='cdrom'>
    <driver name='qemu' type='raw'/>
    <source file='/home/bradmin/vagrant/boxes/arista/veos-4-18-1f-libvirt/Aboot-veos-8.0.0.iso'/>
    <target dev='hdc' bus='ide'/>
    <alias name='ide0-1-0'/>
    <address type='drive' controller='0' bus='1' target='0' unit='0'/>
  <controller type='usb' index='0'>
    <alias name='usb0'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
  <controller type='pci' index='0' model='pci-root'>
    <alias name='pci0'/>
  <controller type='ide' index='0'>
    <alias name='ide0'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
  <interface type='network'>
    <source network='vagrant-libvirt' portgroup='management'/>
    <model type='virtio'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
  <serial type='pty'>
    <source path='/dev/pts/4'/>
    <target port='0'/>
    <alias name='serial0'/>
  <console type='pty' tty='/dev/pts/4'>
    <source path='/dev/pts/4'/>
    <target type='serial' port='0'/>
    <alias name='serial0'/>
  <input type='mouse' bus='ps2'/>
  <graphics type='vnc' port='5903' autoport='yes' listen=''>
    <listen type='address' address=''/>
    <model type='cirrus' vram='9216' heads='1'/>
    <alias name='video0'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
  <memballoon model='virtio'>
    <alias name='balloon0'/>
    <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
<seclabel type='dynamic' model='apparmor' relabel='yes'/>

Create a file called metadata.json with the following contents.


We will need to convert the veos vmdk image to a qemu image.

qemu-img convert -f vmdk -O qcow2 vEOS-lab-4.18.1F.vmdk box.qcow2

Once we have done that we can create a virtual machine with the veos.xml definition file to apply a base config.

virsh define veos.xml

# output
Domain veos defined from veos.xml

Confirm the VM was created.

virsh list --all

# output
Id    Name                           State
-     veos                           shut off

Alright, now lets start the VM.

virsh start veos

# output
Domain veos started

Conenct to the console to apply the bootstrap configuration.

virsh console veos

# output
Connected to domain veos
Escape character is ^]
Switching rootfs

Welcome to Arista Networks EOS 4.18.1F
New seat seat0.
[  OK  ] ConnMgr: Starting TimeAgent: [  OK  ]
Cannot find initial response [FAILED]
Starting ProcMgr: [  OK  ]
Starting EOS initialization stage 1: [   47.644196] NMI watchdog: failed to be enabled on some cpus
[  OK  ]
Starting NorCal initialization: [  OK  ]
Starting EOS initialization stage 2: [  OK  ]
Starting Power On Self Test (POST): [  OK  ]
Completing EOS initialization (press ESC to skip): [  OK  ]
Model and Serial Number: unknown
System RAM: 1893320 kB
Flash Memory size:  3.8G

localhost login: 

Login with the username admin (no password) and apply bootstrap configuration.

conf t
aaa authorization exec default local
user vagrant privilege 15 secret vagrant
user vagrant sshkey ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ== vagrant insecure public key
int management1
    ip address dhcp
    no shutdown
wr mem

Check IP address assigned via DHCP.

show ip int brie

# output
Interface              IP Address         Status     Protocol         MTU
Management1   up         up              1500

From your host terminal confirm you can SSH to the Arista VM with the vagrant ssh key.

# host terminal            
ssh vagrant@ -i ~/.vagrant.d/insecure_private_key

# now in arista VM
localhost#show version 
Arista vEOS
Hardware version:    
Serial number:       
System MAC address:  5254.004b.5f79

Software image version: 4.18.1F
Architecture:           i386
Internal build version: 4.18.1F-4591672.4181F
Internal build ID:      6fcb426e-70a9-48b8-8958-54bb72ee28ed

Uptime:                 6 minutes
Total memory:           1893320 kB
Free memory:            867428 kB


Ok, looks like we are successfully connected. Now poweroff the VM.

sudo poweroff

# output
Flushing AAA accounting queue: [  OK  ]
. <snip>
Storage is finalized.
[  763.709085] System halted.

To exit the console press and hold CTRL and SHIFT while pressing 6 then ]

Even though the eos software is shutdown the VM is still powered on, so poweroff the VM.

virsh destroy veos

# output
Domain veos destroyed

Use the previously downloaded script to create a vagrant box.

bash box.qcow2

# output
==> Creating box, tarring and gzipping
Total bytes written: 619786240 (592MiB, 35MiB/s)
==> created
==> You can now add the box:
==>   'vagrant box add --name box'

Create a metadata file called veos.json so that the box is added with the correct version number.

  "name": "arista/veos",
  "description": "Arista vEOS",
  "versions": [
      "version": "4.18.1F",
      "providers": [
          "name": "libvirt",
          "url": "file:///home/bradmin/vagrant/boxes/arista/veos-4-18-1f-libvirt/"

Add the box to Vagrant.

vagrant box add veos.json

# output
==> box: Loading metadata for box 'veos.json'
box: URL: file:///home/bradmin/vagrant/boxes/arista/veos-4-18-1f-libvirt/veos.json
==> box: Adding box 'arista/veos' (v4.18.1F) for provider: libvirt
box: Unpacking necessary files from: file:///home/bradmin/vagrant/boxes/arista/veos-4-18-1f-libvirt/
==> box: Successfully added box 'arista/veos' (v4.18.1F) for 'libvirt'!

Confirm the box was added successfully

vagrant box add veos.json

# output
arista/veos                          (libvirt, 4.18.1F)
arista/veos                          (virtualbox, 4.16.9M)
arista/veos                          (virtualbox, 4.17.5M)
arista/veos                          (virtualbox, 4.18.1F)

Phew, that was a lot of steps, but thankfully we are finished with the install and ready to test our new Arista Libvirt box.


Now that we have the box installed lets create a Vagrantfile and confirm we can build VM's with Vagrant.

Create a test directory.

mkdir ~/arista-test
cd ~/arista-test

Add a Vagrantfile to the test directory.

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

Vagrant.configure("2") do |config| = "arista/veos"

  # Turn off shared folders
  config.vm.synced_folder ".", "/vagrant", id: "vagrant-root", disabled: true

  # Dont change default SSH key
  config.ssh.insert_key = false

  # Set guest type to prevent guest type detection
  config.vm.guest = :freebsd

  config.vm.provider :libvirt do |domain|
    domain.nic_adapter_count = 1
    domain.cpu_mode = "custom"
    domain.cpu_model = "Hypervisor Default"
    domain.driver = "kvm"
    domain.machine_type = "pc-i440fx-1.5"
    domain.emulator_path = "/usr/bin/qemu-system-x86_64"
    domain.disk_bus = 'ide'
    domain.cpus = 2
    domain.memory = 2048 :file, :device => :cdrom, dev: "hdc", :path => "/home/bradmin/vagrant/boxes/arista/veos-4-18-1f-libvirt/Aboot-veos-8.0.0.iso"
    domain.boot 'cdrom'
    domain.boot 'hd'


Now vagrant up and confirm you can login.

vagrant up --provider=libvirt

# output
Bringing machine 'default' up with 'libvirt' provider...
==> default: Creating image (snapshot of base box volume).
==> default: Creating domain with the following settings...
==> default:  -- Name:              arista-test_default
==> default:  -- Domain type:       kvm
==> default:  -- Cpus:              2
==> default:  -- Feature:           acpi
==> default:  -- Feature:           apic
==> default:  -- Feature:           pae
==> default:  -- Memory:            2048M
==> default:  -- Management MAC:    
==> default:  -- Loader:            
==> default:  -- Base box:          arista/veos
==> default:  -- Storage pool:      default
==> default:  -- Image:             /var/lib/libvirt/images/arista-test_default.img (4G)
==> default:  -- Volume Cache:      default
==> default:  -- Kernel:            
==> default:  -- Initrd:            
==> default:  -- Graphics Type:     vnc
==> default:  -- Graphics Port:     5900
==> default:  -- Graphics IP:
==> default:  -- Graphics Password: Not defined
==> default:  -- Video Type:        cirrus
==> default:  -- Video VRAM:        9216
==> default:  -- Sound Type:	
==> default:  -- Keymap:            en-us
==> default:  -- TPM Path:          
==> default:  -- Boot device:        cdrom
==> default:  -- Boot device:        hd
==> default:  -- CDROMS:            hdc
==> default:  -- CDROM(hdc):        /home/bradmin/vagrant/boxes/arista/veos-4-18-1f-libvirt/Aboot-veos-8.0.0.iso
==> default:  -- INPUT:             type=mouse, bus=ps2
==> default: Creating shared folders metadata...
==> default: Starting domain.
==> default: Waiting for domain to get an IP address...
==> default: Waiting for SSH to become available...
==> default: Configuring and enabling network interfaces...

Confirm you can login to the box.

# Host terminal
vagrant ssh

# Now in vagrant box terminal
localhost#show version 
Arista vEOS
Hardware version:    
Serial number:       
System MAC address:  5254.0085.ed5e

Software image version: 4.18.1F
Architecture:           i386
Internal build version: 4.18.1F-4591672.4181F
Internal build ID:      6fcb426e-70a9-48b8-8958-54bb72ee28ed

Uptime:                 4 minutes
Total memory:           1893320 kB
Free memory:            540216 kB


Awesome, we can build and login to the box with vagrant. Lastly, let clean up a bit.

# back in host shell    
vagrant destroy -f

# output
==> default: Removing domain...


That was a lot more involved than using the off the shelf virtualbox box provided by Arista. For me, the benefits of using the libvirt provider are worth the effort.

Annoying Error

Update 2017-12-03: Configuring the config.vm.guest = :freebsd setting in the Vagrantfile looks to eliminate this error.

Sometimes when building the Vagrant box Vagrant reports the following error. I am not sure why it tries to run these commands and I cannot figure out how to tell it to stop. Note: You can happily ssh to the box so its mostly cosmetic at this point. I am raising a bug report to try and get to the bottom of it.

The following SSH command responded with a non-zero exit status.
Vagrant assumes that this means the command failed!

# Remove any previous network modifications from the interfaces file
sed -e '/^#VAGRANT-BEGIN/,$ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces.pre
sed -ne '/^#VAGRANT-END/,$ p' /etc/network/interfaces | tac | sed -e '/^#VAGRANT-END/,$ d' | tac > /tmp/

cat \
  /tmp/vagrant-network-interfaces.pre \
  /tmp/vagrant-network-entry \
  /tmp/ \
  > /etc/network/interfaces

rm -f /tmp/vagrant-network-interfaces.pre
rm -f /tmp/vagrant-network-entry
rm -f /tmp/

Stdout from the command:


Published: 2017-11-18
Updated: 2017-12-03 - Added Vagrant file setting to prevent error.