If you set up many FreeBSD servers, it is nice to have some automatic installation. This operating system is since FreeBSD 9.0 installed by bsdinstall scripts which support a special file /etc/installerconfig with instructions for unattended installation.

But how to get this file into instalation ISO image? With help of Vagrant. It is so convenient. In a few steps Vagrant will setup a new FreeBSD virtual server in VirtualBox, it connects to this server, downloads specified ISO image, mounts it, makes a copy, adds installerconfig script and finally builds a new ISO which is moved to a shared folder (where your Vagrantfile resides).

1) Install Vagrant and VirtualBox.

2) Setup your Vagrantfile in an empty folder with following content.

ISOURI  = "http://ftp.freebsd.org/pub/FreeBSD/releases/ISO-IMAGES/10.3/FreeBSD-10.3-RELEASE-amd64-disc1.iso"
ISOFILE = ISOURI.match(/.*\/(.+.iso)/)[1]    # eg. FreeBSD-10.3-RELEASE-amd64-bootonly.iso
NEWISO  = ISOFILE.dup.insert(-5,"-custom")   # eg. FreeBSD-10.3-RELEASE-amd64-bootonly-custom.iso

Vagrant.configure("2") do |config|
  config.vm.guest = :freebsd
  # synced_folder is not supported on FreeBSD yet, use NFS
  # config.vm.synced_folder ".", "/vagrant", id: "vagrant-root" #, disabled: true
  config.vm.synced_folder ".", "/vagrant", :nfs => true, id: "vagrant-root"
  config.vm.box = "freebsd/FreeBSD-10.3-STABLE"
  config.ssh.shell = "sh"
  config.vm.network "private_network", ip: "" # some IP from unused subnet
  config.vm.base_mac = "080027D14C66"

  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "1024"]
    vb.customize ["modifyvm", :id, "--cpus", "1"]
    vb.customize ["modifyvm", :id, "--hwvirtex", "on"]
    vb.customize ["modifyvm", :id, "--audio", "none"]
    vb.customize ["modifyvm", :id, "--nictype1", "virtio"]
    vb.customize ["modifyvm", :id, "--nictype2", "virtio"]

  $script = <<SCRIPT
    echo Setting up ...
    env ASSUME_ALWAYS_YES=YES pkg install rsync cdrtools
    echo Fetching #{ISOURI} ...
    mkdir -p /home/iso
    fetch -m -o /home/iso/#{ISOFILE} #{ISOURI}

    echo Prepairing #{ISOFILE} ...
    mkdir -p /mnt/freebsd-iso
    mdconfig -f /home/iso/#{ISOFILE}
    mount -t cd9660 /dev/md0 /mnt/freebsd-iso
    #rm -rf /mnt/custom-freebsd-iso
    rsync -aq /mnt/freebsd-iso/ /mnt/custom-freebsd-iso
    umount /mnt/freebsd-iso
    mdconfig -d -u 0

    cp /vagrant/installerconfig /mnt/custom-freebsd-iso/etc/

    CUSTOM_ISO_TITLE=$(isoinfo -d -i /home/iso/#{ISOFILE} | grep "Volume id" | awk '{print $3}')
    echo Creating iso $CUSTOM_ISO_TITLE into #{NEWISO} ...
    mkisofs --quiet -J -R -no-emul-boot -V $CUSTOM_ISO_TITLE -p "XNET" -b boot/cdboot -o /vagrant/#{NEWISO} /mnt/custom-freebsd-iso

  config.vm.provision "shell", inline: $script


You can configure desired FreeBSD version by changing path to original ISO file.

ISOURI  = "http://ftp.freebsd.org/pub/FreeBSD/releases/ISO-IMAGES/10.3/FreeBSD-10.3-RELEASE-amd64-disc1.iso"

3) Add your installerconfig script to this folder.

4) Run

$ vagrant up

5) Profit from your custom ISO file that magically appeared in your folder.

Thats all! So easy …

If you need to change your installerconfig, simply change the file contents and re-run vagrant with:

$ vagrant provision

and your ISO file will change in a minute.

If you are happy with your image, don’t forget to cleanup.

$ vagrant destroy

Based on: