Build a FreeBSD 10.0-release Openstack Image with bsd-cloudinit

11-06-2014 | Remy van Elst

We are going to prepare a FreeBSD image for Openstack deployment. We do this by creating a FreeBSD 10.0-RELEASE instance, installing it and converting it using bsd-cloudinit. We'll use the CloudVPS public Openstack cloud for this. Create an account there and install the Openstack command line tools, like nova, cinder and glance. This tutorial is more a collection of notes than what you are used of me, it has less explanation and such, just right on steps to get started.

You can see all my Openstack related articles here. For example, how to use Duplicity to create Encrypted backups to the Openstack Swift Object Store

If you like this article, consider sponsoring me by trying out a Digital Ocean VPS. With this link you'll get a $5 VPS for 2 months free (as in, you get $10 credit). (referral link)

This tutorial is also available for FreeBSD 10.1-RELEASE. That one is more comprehensive and has more background information, plus compression and username changes.

Set the correct environment variables:

export OS_AUTH_URL=""
export OS_TENANT_NAME="<tenant name>"
export OS_USERNAME="<username>"
export OS_PASSWORD="<password>"
export OS_TENANT_ID="<tenant id>"

Start by downloading the 10.0-RELEASE iso:


Upload it to Openstack:

glance image-create --file Downloads/FreeBSD-10.0-RELEASE-amd64-disc1.iso --name "FreeBSD-10.0-RELEASE-amd64-disc1.iso" --disk-format iso --container-format bare --progress

Create the root volume for our FreeBSD preparation install:

cinder create --display-name "freebsd-10-root" 8

Boot a new instance from the ISO, attaching the volume we just created ad well:

nova boot --image <freebsd iso image id> --flavor "Standard 1" --availability-zone NL1 --nic net-id=00000000-0000-0000-0000-000000000000 --block-device-mapping hdb=<volume freebsd-10-root id>:::0 FreeBSD-10.0-RELEASE-install

Do a standard install of FreeBSD 10:

  • default keymap
  • hostname:
  • Just lib32 and ports, no doc, games or src
  • Partition Layout:
    • ada0 GPT
    • ada0p1 64kb freebsd-boot
    • ada0p2 512MB freebsd-swap
    • ada0p3 7GB freebsd-root mountpoint /
  • Root password P@ssw0rd
  • Network:
    • adapter: vtnet0
    • ipv4: dhcp
    • ipv6: slaac
    • search:
  • UTC: no, timezone 8 EUROPE 34 NETHERLANDS
  • Services at boot: sshd, ntpd, moused, dumpd
  • Extra user:
    • Username: freebsd
    • Full name: freebsd
    • uid: default
    • Login group: default
    • Other groups: wheel
    • Login class: default
    • Shell: tcsh
    • Home: default
    • Home permissions: default
    • Password auth: yes
    • Empty password: no
    • Random password: no
    • Password: P@ssw0rd
    • Lock out: no
    • OK: yes
    • Another user: no
  • Exit

After install, edit /etc/fstab, changing ada0 to vtbd0. This is for VirtIO support.

Shut the instance from FreeBSD using shutdown -p now and after that via nova:

nova stop <install vm id>

Detach the volume:

nova volume-detach <install vm id> <install root volume id>

Boot a new instance with the installed freebsd volume as the root volume:

nova boot --block-device source=volume,id=<root volume id>,dest=volume,shutdown=preserve,bootindex=0 --flavor "Standard 1" --availability-zone NL1 --nic net-id=00000000-0000-0000-0000-000000000000  FreeBSD-10.0-RELEASE-configure

If you get a mountroot error, enter the following: ufs:/dev/vtbd0p3.

Change /etc/fstab after the fact, change ada0 to vtbd0 for VirtIO support.

Set the default route:

route add default `ifconfig vtnet0 | grep "inet " | cut -d" " -f 2 | awk -F. '{print $1"."$2"."$3".1" }'`

Also put it in /etc/rc.local to make sure it works on bootup.

Bootstrap pkg:


Enter y.

Install vim and py27-setuptools (for bsd-cloudinit):

pkg install vim-lite py27-setuptools

Add your SSH key:

mkdir /root/.ssh
chmod 700 /root/.ssh
echo "ssh-rsa AAAA[...]" > /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys

Install python modules for bsd-cloudinit:

easy_install eventlet
easy_install iso8601

Add the following to /boot/loader.conf to make sure the console works:


Now do any other customizations you want to have in your image.

Do the bsd-cloudinit install:

fetch --no-verify-peer
chmod +x
set history = 0
history -c

Turn the machine off:

shutdown -p now

Terminate the machine, otherwise you cannot detach the volume (ERROR: Can't detach root device volume (HTTP 403)):

nova delete <id of freebsd-configure vm)

Convert the volume to an image:

cinder upload-to-image <freebsd-10-root volume id> FreeBSD-10.0-RELEASE-cloudinit

This might take a while.

Set the min-disk and min-ram requirements, plus some more properties for the image:

glance image-update --min-disk 8 --min-ram 1024 --property architecture=x86_64 --property image_supports_keypair=true --property image_supports_password=true --property supported=false <id from the converted volume image>

If needed, make it public:

glance --name "UNSUPPORTED: FreeBSD-10.0-RELEASE" --is-public True <id from the converted volume image>

That's it. You are done and have a good workable freebsd image.

Boot a new instance from your newly created image:

nova boot --image <id from the converted volume image> --flavor "Standard 4" --availability-zone NL1 --nic net-id=00000000-0000-0000-0000-000000000000 --key-name <your ssh key> FreeBSD-10.0-RELEASE-cloudinit

When the instance has spawned you can login as the freebsd user, freebsd@ipaddress.

Tags: cloud, cloudinit, compute, freebsd, image, openstack, python,