I'll elaborate a bit on the suggestion to also consider VNET jails: With VNET, jails give you a "userspace virtual machine"; separation should be comparable. You can use
epair(4) interfaces for the jails and plug them into a
bridge(4) to have them in a separate virtual network, just like you would with the
tap(4) interfaces used for a byhve vm.
The advantage of a jail is: It's running on the same kernel, so there's less overhead, it can just use a reserved part of the host's filesystem (and if necessary, you can delegate it ZFS datasets to manage them inside the jail) and shares the RAM, so no need to "wire" a substantial part of RAM (that can't be swapped) just for the virtual machine. You can run older versions of FreeBSD in a jail, as long as your kernel has compatibility enabled (which is the default), or even Linux, if the kernel has Linux compatibility (also the default), but I wouldn't recommend the latter, as the compatibility with Linux isn't perfect and there are pitfalls.
Of course, if you need a different OS, or only a newer FreeBSD version, or a kernel compiled with different options, you can't use a jail and need bhyve. But you can easily mix both, that's what I'm doing. Maybe to give some ideas, I'll share part of my setup:
I'm using a bhyve VM for routing and firewalling. If you can afford to run a separate phyiscal box for firewalling, consider doing so, because no VM or jail can ever 100% guarantee no "break-out" is possible, so if an attacker breaks out of a different jail or VM on the same host, they can also control the firewall. But at least, this risk is relatively small, and putting the firewall in a VM is the next best thing you can do (better than firewalling directly on the host).
So, this firewall VM needs bhyve, to be able to "PCI pass-through" all physical NICs to it. It also has several virtual network interfaces, and the host-side
tap(4) interfaces are plugged into different bridges to form different virtual subnets.
Then, I also have e.g. a Windows machine in bhyve.
For most other things, I use VNET jails here. For example, one jail is an AD DC (with samba), another is a samba fileserver (for windows clients to access home etc.), yet another one provides a webserver, etc. – using bhyve for all these would be unnecessary overhead
Finally, I support
diego's suggestion to use
sysutils/vm-bhyve, it's a nice little management tool. If you use ZFS, consider creating a sparse zvol to back your virtual harddisk – this is also supported by vm-bhyve, just look at the docs. If you make sure the guest has TRIM enabled, you will see the zvol shrink again when blocks on the virtual harddisk aren't used any more.
And yet another hint: You should use "virtio" drivers in your guests for disk and network, this should give the best performance. FreeBSD and Linux come with the necessary drivers, for Windows guests you can install them from here:
https://github.com/virtio-win/virtio-win-pkg-scripts/blob/master/README.md