Intro

In this post I will cover how to create a Cisco IOSv 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.

Note
I am using an IOSv image that is available with a Cisco VIRL subscription. I do not know if the image is available without a VIRL subscription.

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

  • IOSv - vios-adventerprisek9-m.vmdk.SPA.156-1.T
  • Vagrant - Vagrant 2.1.0
  • vagrant-libvirt - 0.0.43

Download

Navigate to the Cisco software download page and download the vios-adventerprisek9-m.vmdk.SPA.156-1.T image.

Install

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

cmd
mkdir -p ~/vagrant/boxes/cisco/iosv
cd ~/vagrant/boxes/cisco/iosv

Copy the iosv files downloaded earlier to the ~/vagrant/boxes/cisco/iosv/ directory.

cmd
cp ~/Downloads/vios-adventerprisek9-m.vmdk.SPA.156-1.T .

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.

cmd
curl -O https://raw.githubusercontent.com/vagrant-libvirt/vagrant-libvirt/master/tools/create_box.sh

Convert the vmdk disk to the qcow2 format for use with KVM.

cmd
qemu-img convert -f vmdk -O qcow2 vios-adventerprisek9-m.vmdk.SPA.156-1.T iosv.qcow2

Launch the Cisco IOSv VM in order to apply a bootstrap config to it that allows Vagrant to login and manage the box.

cmd
virt-install \
    --connect=qemu:///system \
    --network network=vagrant-libvirt,model=e1000 \
    --name=iosv \
    --cpu host \
    --arch=x86_64 \
    --machine=pc-1.0 \
    --vcpus=1 \
    --ram=512 \
    --os-type=linux \
    --noacpi \
    --virt-type=kvm \
    --watchdog i6300esb,action=reset \
    --disk path=iosv.qcow2,format=qcow2,device=disk,bus=virtio,cache=writethrough \
    --graphics none \
    --import

You will be connected to the console. Enter no when the highlighted section is presented.

cmd
# output

                             GNU GRUB  version 2.00

 +--------------------------------------------------------------------------+
 |                                                                          |
 |IOSv                                                                      |
 |                                                                          |
  Booting `IOSv'

error: Can't get controller info..
Booted IOSv. Boot args: [/vios-adventerprisek9-m]

Smart Init is enabled

<snip>
.
.
         --- System Configuration Dialog ---

Would you like to enter the initial configuration dialog? [yes/no]: no


Press RETURN to get started!
.
.
<snip>

Router>

Apply bootstrap configuration.

cmd
!
en
conf t
hostname iosv
!
ip domain-name lab.local
!
crypto key generate rsa modulus 2048
ip ssh version 2
!
aaa new-model
!
aaa authentication login default local
aaa authorization exec default local
!
username vagrant privilege 15 secret vagrant
!
ip ssh pubkey-chain
  username vagrant
    key-hash ssh-rsa DD3BB82E850406E9ABFFA80AC0046ED6
!
vrf definition MGMT
 description Management interface
 !
 address-family ipv4
 exit-address-family
!
interface GigabitEthernet0/0
  description vagrant-management
  vrf forwarding MGMT
  ip address dhcp
  duplex auto
  speed auto
  media-type rj45
  no shutdown
!
line vty 0 4
 transport input ssh
!
event manager applet ENABLE-MGMT
 event syslog pattern "SYS-5-RESTART"
 action 0 cli command "enable"
 action 1 cli command "conf t"
 action 2 cli command "crypto key generate rsa modulus 2048"
 action 3 cli command "interface GigabitEthernet0/0"
 action 4 cli command "no shutdown"
 action 5 cli command "exit"
!
end
wr mem
!

This configuration allows Vagrant to assign an IP address to the management interface via DHCP and to also ssh to the guest using ssh keys. There is an EEM script ENABLE-MGMT that is required to generate the SSH keys and enable the management interface on boot.

Important
Without the EEM script Vagrant will not be able to manage the box. The SSH keys are not preserved between reboots and the GigabitEthernet0/0 interface will be shutdown on boot, I think this is due to the MAC address changing.

Check the IP address assigned via DHCP.

cmd
show ip int brie

# output

Interface                  IP-Address      OK? Method Status                Protocol
GigabitEthernet0/0         192.168.121.63  YES DHCP   up                    up

From your host terminal confirm you can SSH to the Cisco IOSv VM with the vagrant SSH key.

cmd
# host terminal

ssh vagrant@192.168.121.63 -i ~/.vagrant.d/insecure_private_key

# now in IOSv VM

Warning: Permanently added '192.168.121.63' (RSA) to the list of known hosts.

**************************************************************************
* IOSv is strictly limited to use for evaluation, demonstration and IOS  *
* education. IOSv is provided as-is and is not supported by Cisco's      *
* Technical Advisory Center. Any use or disclosure, in whole or in part, *
* of the IOSv Software or Documentation to any third party for any       *
* purposes is expressly prohibited except as otherwise authorized by     *
* Cisco in writing.                                                      *
**************************************************************************

**************************************************************************
* IOSv is strictly limited to use for evaluation, demonstration and IOS  *
* education. IOSv is provided as-is and is not supported by Cisco's      *
* Technical Advisory Center. Any use or disclosure, in whole or in part, *
* of the IOSv Software or Documentation to any third party for any       *
* purposes is expressly prohibited except as otherwise authorized by     *
* Cisco in writing.                                                      *
**************************************************************************
iosv#exit
Connection to 192.168.121.63 closed.

If you successfully connected, exit and power off the VM.

To exit the console use one of these key combinations (Assuming English keyboard).

  • CTRL + ]
  • CTRL + 5
  • Press and hold CTRL and SHIFT while pressing 6 then ]

Now power off the VM.

cmd
virsh destroy iosv

# output

Domain iosv destroyed

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

file
{"provider":"libvirt","format":"qcow2","virtual_size":2}

Use the previously downloaded script create_box.sh to create a vagrant box.

cmd
bash create_box.sh iosv.qcow2

# output

{2}
==> Creating box, tarring and gzipping
./metadata.json
./Vagrantfile
./box.img
Total bytes written: 123637760 (118MiB, 15MiB/s)
==> iosv.box created
==> You can now add the box:
==>   'vagrant box add iosv.box --name iosv'

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

file
{
  "name": "cisco/iosv",
  "description": "Cisco IOSv",
  "versions": [
    {
      "version": "15.6-1-T",
      "providers": [
        {
          "name": "libvirt",
          "url": "file:///home/bradmin/vagrant/boxes/cisco/iosv/iosv.box"
        }
      ]
    }
  ]
}

Add the box to Vagrant.

cmd
vagrant box add iosv.json

# output

==> box: Loading metadata for box 'iosv.json'
    box: URL: file:///home/bradmin/vagrant/boxes/cisco/iosv/iosv.json
==> box: Adding box 'cisco/iosv' (v15.6-1-T) for provider: libvirt
    box: Unpacking necessary files from: file:///home/bradmin/vagrant/boxes/cisco/iosv/iosv.box
==> box: Successfully added box cisco/iosv' (v15.6-1-T) for 'libvirt'!

Confirm the box was added successfully

cmd
vagrant box list

# output

CumulusCommunity/cumulus-vx          (libvirt, 3.4.2)
arista/veos                          (libvirt, 4.20.1F)
cisco/asav                           (virtualbox, 9.8.1)
cisco/csr1000v                       (libvirt, 03.15.00.S-155-2-S)
cisco/iosv                           (libvirt, 15.6-1-T)

Testing

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

Create a test directory.

cmd
mkdir ~/iosv-test
cd ~/iosv-test

Add a Vagrantfile to the test directory with the following contents

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

Vagrant.configure("2") do |config|
  config.vm.define "rt01" do |node|
    node.vm.box = "cisco/iosv"

    # Turn off shared folders
    node.vm.synced_folder ".", "/vagrant", disabled: true

    # Do not try to insert new SSH key
    node.ssh.insert_key = false

    # Give VM time to boot
    node.vm.boot_timeout = 180

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

    # Provider-specific configuration
    node.vm.provider :libvirt do |domain|
      domain.nic_adapter_count = 8
      domain.memory = 512
      domain.cpus = 1
      domain.driver = "kvm"
      domain.nic_model_type = "e1000"
    end

  end
end

Now vagrant up and confirm you can login.

cmd
vagrant up

# output

Bringing machine 'rt01' up with 'libvirt' provider...
==> rt01: Checking if box 'cisco/iosv' is up to date...
==> rt01: Creating image (snapshot of base box volume).
==> rt01: Creating domain with the following settings...
==> rt01:  -- Name:              iosv_rt01
==> rt01:  -- Domain type:       kvm
==> rt01:  -- Cpus:              1
==> rt01:
==> rt01:  -- Feature:           acpi
==> rt01:  -- Feature:           apic
==> rt01:  -- Feature:           pae
==> rt01:  -- Memory:            512M
==> rt01:  -- Management MAC:
==> rt01:  -- Loader:
==> rt01:  -- Base box:          cisco/iosv
==> rt01:  -- Storage pool:      default
==> rt01:  -- Image:             /var/lib/libvirt/images/iosv_rt01.img (2G)
==> rt01:  -- Volume Cache:      default
==> rt01:  -- Kernel:
==> rt01:  -- Initrd:
==> rt01:  -- Graphics Type:     vnc
==> rt01:  -- Graphics Port:     -1
==> rt01:  -- Graphics IP:       127.0.0.1
==> rt01:  -- Graphics Password: Not defined
==> rt01:  -- Video Type:        cirrus
==> rt01:  -- Video VRAM:        9216
==> rt01:  -- Sound Type:
==> rt01:  -- Keymap:            en-us
==> rt01:  -- TPM Path:
==> rt01:  -- INPUT:             type=mouse, bus=ps2
==> rt01: Creating shared folders metadata...
==> rt01: Starting domain.
==> rt01: Waiting for domain to get an IP address...
==> rt01: Waiting for SSH to become available...
==> rt01: Configuring and enabling network interfaces...

Confirm you can login to the box.

cmd
# Host terminal

vagrant ssh

# Now in vagrant box terminal

**************************************************************************
* IOSv is strictly limited to use for evaluation, demonstration and IOS  *
* education. IOSv is provided as-is and is not supported by Cisco's      *
* Technical Advisory Center. Any use or disclosure, in whole or in part, *
* of the IOSv Software or Documentation to any third party for any       *
* purposes is expressly prohibited except as otherwise authorized by     *
* Cisco in writing.                                                      *
**************************************************************************

iosv#show version
Cisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.6(1)T, RELEASE SOFTWARE (fc1)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2015 by Cisco Systems, Inc.
Compiled Fri 20-Nov-15 13:39 by prod_rel_team


ROM: Bootstrap program is IOSv

iosv uptime is 1 minute
System returned to ROM by reload
System image file is "flash0:/vios-adventerprisek9-m"
Last reload reason: Unknown reason



This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to
export@cisco.com.

Cisco IOSv (revision 1.0) with  with 496897K/25600K bytes of memory.
Processor board ID 9YGHKHUSEIFBLTHVGUKBJ
1 Gigabit Ethernet interface
DRAM configuration is 72 bits wide with parity disabled.
256K bytes of non-volatile configuration memory.
2097152K bytes of ATA System CompactFlash 0 (Read/Write)
0K bytes of ATA CompactFlash 1 (Read/Write)
0K bytes of ATA CompactFlash 2 (Read/Write)
0K bytes of ATA CompactFlash 3 (Read/Write)



Configuration register is 0x0

iosv#

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

cmd
# back in host shell

vagrant destroy -f

# output

==> rt01: Removing domain...

Remove the original KVM image.

cmd
rm -f iosv.qcow2
virsh undefine iosv

# output

Domain iosv has been undefined

Outro

Compared to the CSR1000v the IOSv image is more lightweight, it requires much less resources and is a lot faster to boot up. Now that you have an IOSv image in your Vagrant arsenal go out and give your old pal Cisco some network automation love.