Use cloud-init with VirtualBox?

Cloudinit is used by many cloud images e.g. on EC2 to obtain their initial configuration, like IP address, ssh keys and the like. Is there a way of using it with VirtualBox in a similar way?

I'm looking for a way of putting an ssh authorized_keys file on an VirtualBox instance without having to hard-code it into the image itself.

There is a section on "No Cloud" here but I'm not entirely understanding how this would apply to VirtualBox. Can I generate a /dev/sdb with the files in question, and provide this to VirtualBox as a second drive before booting the instance, and it somehow magically will pick the info up?


I figured it out and blogged about it here. From that link:

#VirtualBox and cloud-init

In case somebody else wants to know:

  • You can use cloud-init to configure VirtualBox virtual machines without too much trouble.

  • One way of doing this is to use a “config drive”, i.e. to mount another virtual hard drive that (only) has the cloud-init configuration data on it.

  • Here’s a way of creating it:

      # Create empty virtual hard drive file
      dd if=/dev/zero of=config.img bs=1 count=0 seek=2M
      # put correct filesystem and disk label on
      mkfs.vfat -n cidata config.img
      # mount it somewhere so you can put the config data on
      sudo mount config.img /mnt
    
  • Now put your config data into /mnt/user-data and /mnt/meta-data,

  • Example: /mnt/user-data. This will create a user ubos-admin with a ssh key so you can log on via ssh without a password.

      #cloud-config
      users:
       - name: ubos-admin
         gecos: UBOS administrative user
         ssh-authorized-keys:
          - insert ssh key here
         sudo: "ALL=(ALL) NOPASSWD: /usr/bin/ubos-admin *, /usr/bin/bash *"
    
  • Example /mnt/meta-data:

      instance-id: my-instance-1
    
  • Then, unmount:

      sudo umount /mnt
    
  • and attach as second hard drive before you boot. If cloud-init is installed in the main image, it should pick up the configuration info.

  • The .vmdk image file for this second hard drive can be created using the following commands, if you are on a Linux distro that uses apt:

     sudo apt-get install qemu-kvm
     qemu-img convert -O vmdk  config.img config.vmdk
    

A slightly different approach that also works:

Using the CentOS 7 Cloud Image found here: https://cloud.centos.org/centos/7/images/ (choose CentOS-7-x86_64-GenericCloud.qcow2)

user-data

#!/bin/bash
##
## dependencies required for:
##        VBoxGuestAdditions
##        Minimal Desktop
##
DEPS='wget unzip python-pip git gnome-classic-session gnome-terminal nautilus-open-terminal control-center liberation-mono-fonts bzip2 libguest libguestfs binutils gcc make kernel-headers kernel-devel'

update(){
    sudo yum -y -q update
}


install_epel(){
    sudo yum -y install epel-release
    sudo yum -y update
}

configure(){
    sudo yum -y -q install $DEPS
    yum -y groupinstall "X Window System"
    unlink /etc/systemd/system/default.target
    ln -sf /lib/systemd/system/graphical.target /etc/systemd/system/default.target

    reboot
}

set -x
update
install_epel
configure

meta-data

instance-id: dev
local-hostname: dev.example.com
public-keys:
    - ssh-rsa AAAAB3NzaC1y[...]2yX3 [email protected]

network-interfaces: |
    auto eth1
    iface eth1 inet dhcp

vbox-config-drive.sh

#!/bin/bash

##
## generate the config-drive iso
##
gen_iso(){
    echo "Generating ISO"
    genisoimage -output vbox-config.iso -volid cidata -joliet -r meta-data user-data
}

##
## resize as necessary
##
resize(){
    echo "Resizing Disk"
    qemu-img create -f qcow2 -o preallocation=metadata CentOS-7-x86_64-GenericCloud.qcow2.new 12G
    virt-resize --quiet --expand /dev/sda1 CentOS-7-x86_64-GenericCloud.qcow2 CentOS-7-x86_64-GenericCloud.qcow2.new
    mv CentOS-7-x86_64-GenericCloud.qcow2.new CentOS-7-x86_64-GenericCloud.qcow2
}
##
## convert the qcow to vmdk
##
make_vmdk(){
    echo "Converting QCOW to VMDK"
    qemu-img convert -f qcow2 CentOS-7-x86_64-GenericCloud.qcow2 -O vmdk CentOS-7-x86_64-GenericCloud.vmdk
}

gen_iso
##
## OPTIONAL
## resize
##
make_vmdk
echo "Done"

Use the resulting VMDK as your VirtualBox primary disk and the resulting ISO as the optical drive.

Hope this helps. M.