Creating VirtualBox Lab Environments Using Cloud Images

Lately, I have been using VirtualBox more often to adjust and follow existing learning or lab environments that already use VirtualBox as the standard virtualization platform.

One thing that bothered me was how repetitive the VM setup process usually is:

Compared to other virtualization platforms or cloud providers, this process felt very slow and inefficient.

Because of that, I started using Ubuntu Cloud Images combined with Cloud-Init to make VirtualBox environments faster and easier to provision.

With this approach:

I only need to:


Environment


Create meta-data

The meta-data file is used by cloud-init to identify the instance information such as:

This helps cloud-init recognize the VM during the initialization process when the machine boots for the first time.

Create a file named:

meta-data

Content:

instance-id: machine
local-hostname: machine

Create user-data

The user-data file is used to automate the initial VM configuration process during the first boot using cloud-init.

In my case, I use this configuration because I want the VM to be immediately ready to use without additional manual setup after booting.

Some configurations that I usually need are:

This approach helps speed up lab provisioning, especially when repeatedly rebuilding VirtualBox environments for learning or testing purposes.

Create a file named:

user-data

Content:

#cloud-config
hostname: machine

package_update: true
package_upgrade: true

packages:
  - openssh-server

users:
  - name: ubuntu
    sudo: ALL=(ALL) NOPASSWD:ALL
    groups: sudo
    shell: /bin/bash
    lock_passwd: false
    ssh_authorized_keys:
      - "my-pub-key"

  - name: root
    ssh_authorized_keys:
      - "my-pub-key"

write_files:
  - path: /etc/sysctl.d/99-disable-ipv6.conf
    content: |
      net.ipv6.conf.all.disable_ipv6 = 1
      net.ipv6.conf.default.disable_ipv6 = 1
      net.ipv6.conf.lo.disable_ipv6 = 1
    owner: root:root
    permissions: '0644'

  - path: /etc/ssh/sshd_config.d/99-custom.conf
    content: |
      Port 22
      PermitRootLogin prohibit-password
      PubkeyAuthentication yes
    owner: root:root
    permissions: '0644'

  - path: /etc/systemd/resolved.conf.d/dns.conf
    content: |
      [Resolve]
      DNS=8.8.8.8
      FallbackDNS=1.1.1.1
    owner: root:root
    permissions: '0644'

runcmd:
  - sysctl --system
  - systemctl enable ssh
  - systemctl restart ssh
  - ufw allow 22
  - ufw enable

Configure Network

The network-config file is used to configure VM networking automatically during the first boot process.

In my case, I use two network adapters in VirtualBox:

Using network-config helps avoid manual network configuration after the VM boots.

This configuration is useful because:

Create a file named:

network-config

Content:

#cloud-config
network:
  version: 2
  ethernets:
    enp0s3:
      dhcp4: true
      dhcp6: false
      link-local: []

    enp0s8:
      dhcp4: false
      dhcp6: false
      link-local: []
      addresses:
        - 192.168.56.10/24

      routes:
        - to: 192.168.56.0/24
          via: 192.168.56.1
          metric: 100

Generate Cloud-Init ISO

After creating all required files:

the next step is to generate a cloud-init ISO image.

This ISO file will later be attached to the VirtualBox VM and used by cloud-init during the first boot process to automatically apply the VM configuration.

If the mkisofs command is not available yet, install the required package first.

For Ubuntu/Debian:

sudo apt install genisoimage -y

After the package is installed, generate the ISO using:

mkisofs -output cloud-init.iso \
-volid cidata \
-joliet \
-rock \
user-data meta-data network-config

Explanation:

After the ISO is generated successfully, attach it to the VirtualBox VM together with the Ubuntu cloud image before booting the machine.


VirtualBox Configuration

After creating the cloud-init configuration files and generating the cloud-init ISO, the next step is adjusting the VirtualBox VM configuration so the VM can properly use the Ubuntu cloud image and cloud-init configuration during boot.

In my case, I use:

The NAT adapter is used for internet access, while the Host-Only adapter is used for SSH access and internal lab communication.

Then configure the VM by:

Once the VM boots for the first time, cloud-init will automatically read the configuration from the attached ISO and apply all predefined settings.

After the VM boots:

I can directly SSH into the VM:

This setup helps speed up VirtualBox lab provisioning because most of the initial machine configuration is already automated during the first boot process.


Notes

This setup is based on my personal learning and lab environment needs using VirtualBox.

I have already tested this method myself and it works quite well for quickly provisioning VirtualBox lab environments using Ubuntu Cloud Images and Cloud-Init.

I created this note mainly because I tend to forget the setup steps after some time, so when I need it again in the future, I can simply revisit this personal note instead of repeating the troubleshooting and research process from the beginning.

This is also one of the approaches I found from browsing and experimenting. There are probably many other methods that may be simpler, cleaner, or more automated than this setup.

However, for my current learning environment and workflow, this approach is already practical enough and helps speed up repeated VM provisioning tasks in VirtualBox.