I have something like that in my notes, but it is for installing Fedora Linux on ZFS. FWIW, I can share it here. 
Guide
Boot a Fedora Linux live image and start a terminal session.
# become root
sudo -i
# locate at least two identical drives to be partitioned and formatted
lsblk --nodeps --paths -o name,size,model
# erase all the partitions and filesystems from the disks
wipefs -a /dev/sda
wipefs -a /dev/sdb
# install the gdisk package which provides the sgdisk (scripted-gdisk) command
dnf install -y gdisk
# on each disk, create two partitions – the first partition will be the ESP and the second will be for ZFS
sgdisk -n 0:0:+4GiB -t 0:ef00 -c 0:"boot@a" /dev/sda
sgdisk -n 0:0:0 -t 0:8304 -c 0:"root@a" /dev/sda
sgdisk -n 0:0:+4GiB -t 0:ef00 -c 0:"boot@b" /dev/sdb
sgdisk -n 0:0:0 -t 0:8304 -c 0:"root@b" /dev/sdb
# verify that things look right so far
lsblk -Q 'TYPE=="part"' --paths -o name,size,parttypename,partlabel
NAME SIZE PARTTYPENAME PARTLABEL
/dev/sda1 4G EFI System boot@a
/dev/sda2 890.3G Linux root (x86-64) root@a
/dev/sdb1 4G EFI System boot@b
/dev/sdb2 890.3G Linux root (x86-64) root@b
# format the ESPs with the VFAT filesystem
mkfs.vfat /dev/sda1
mkfs.vfat /dev/sdb1
# if df -h /run shows a size less than 3G, increase it.
[[ $(($(findmnt -nbo size /run)/10**9)) -lt 3 ]] && mount -o remount,size=3G /run
# remove the deprecated zfs-fuse package if it is installed
rpm -e --nodeps zfs-fuse
# download and install the latest zfs-release repo and OpenPGP certificate
git clone --no-checkout --depth 1 https://github.com/zfsonlinux/zfsonlinux.github.com/ ~/zfs-release
cd ~/zfs-release
git restore --staged fedora && git restore fedora
source /etc/os-release
find ~/zfs-release \
| grep "zfs-release-[0-9]\+-[0-9]\+.fc${VERSION_ID}.noarch.rpm" \
| sort | tail -n 1 | xargs -r dnf install -y
# install and activate zfs
dnf install -y --repo=fedora kernel-devel
dnf install -y zfs
modprobe zfs
# generate a random hostid (stored at /etc/hostid)
zgenhostid
# format the remaining partitions with ZFS
PROPS=(
-o ashift=12
-O mountpoint=none
-O acltype=posix
-O canmount=off
-O compression=on
-O dnodesize=auto
-O relatime=on
-O xattr=sa
)
zpool create -f -R /mnt "${PROPS[@]}" root mirror /dev/disk/by-partlabel/root@{a,b}
# verify that the ZFS pool looks correct
zpool list -v
# create a new filesystem on the ZFS pool and mount it
zfs create -o canmount=noauto -o mountpoint="/" root/0
zfs mount root/0
# verify that the new ZFS root filesystem is mounted at /mnt
findmnt /mnt
TARGET SOURCE FSTYPE OPTIONS
/mnt root/0 zfs rw,relatime,seclabel,xattr,posixacl,casesensitive
# set up a chroot environment for the OS installation
ALTROOT=/mnt
BINDMNT=(dev proc sys run)
for i in "${BINDMNT[@]}"; do
mount -o X-mount.mkdir=755 --rbind "/$i" "$ALTROOT/$i"
mount --make-rslave "$ALTROOT/$i"
done
mount -o X-mount.mkdir=755 --bind "/tmp" "$ALTROOT/tmp"
# define a list of packages to be excluded from the installation
XXX=(
grub2-\*
os-prober
dracut-config-rescue
zfs-fuse
avahi
)
# common parameters for the next few dnf runs
PARAMS=(
-y
--use-host-config
--installroot=/mnt
--repo=fedora
--releasever=${VERSION_ID:?}
)
# install Fedora Linux on the new ZFS filesystem
dnf "${PARAMS[@]}" "${XXX[@]/*/--exclude=&}" group install core
# make sure the excluded packages are blocked from future installation
(
IFS=','
chroot /mnt env LANG=C dnf config-manager setopt "excludepkgs=${XXX[*]}"
)
# set a password for the root account
chroot /mnt passwd root
# for server installations, show the service OK/FAILED status on boot-up
dnf "${PARAMS[@]}" install plymouth-theme-script
chroot /mnt plymouth-set-default-theme details
# remove old/invalid UEFI boot entries
dnf "${PARAMS[@]}" install efibootmgr
for i in $(efibootmgr | grep -i '^boot[0-9a-f]\{4\}' | cut -c 5-8); do
efibootmgr -b "$i" -B
done
# remove any content that might have been copied to /boot
rm -rf /mnt/boot/*
# mount the first ESP under the new OS’s mountpoint
MNT_OPTS=(
dmask=0077
fmask=0177
context=system_u:object_r:boot_t:s0
shortname=lower
flush
discard
noexec
nodev
nosuid
nosymfollow
)
mkdir /mnt/boot@a
(
IFS=','
mount -o "${MNT_OPTS[*]:?}" /dev/sda1 /mnt/boot@a
)
mount -o bind /mnt/boot@a /mnt/boot
# install and configure systemd-boot
dnf "${PARAMS[@]}" install systemd-boot-unsigned
chroot /mnt bootctl install --graceful --no-variables --esp-path=/boot
cat << END > /mnt/etc/kernel/cmdline
root=zfs:root/0 quiet rhgb
END
cat << END > /mnt/etc/kernel/install.conf
layout=bls
BOOT_ROOT=/boot
END
cat << 'END' > /mnt/etc/kernel/install.d/91-loaderentry-update-title.install
#!/usr/bin/sh
set -e
trap 'exit 0' exit
COMMAND="${1:?}"
KERNEL_VERSION="${2:?}"
[ "$COMMAND" = "add" ]
[ "$KERNEL_INSTALL_LAYOUT" = "bls" ]
ENTRY_TOKEN="${KERNEL_INSTALL_ENTRY_TOKEN:?}"
BOOT_ROOT="${KERNEL_INSTALL_BOOT_ROOT:?}"
LOADER_ENTRY="$BOOT_ROOT/loader/entries/$ENTRY_TOKEN-$KERNEL_VERSION.conf"
ROOTFS=''
for option in $(grep '^options\s' "$LOADER_ENTRY"); do
ROOTFS="$(expr "$option" : 'root=zfs:\(.*\)')" && break
done
[ -n "$ROOTFS" ]
sed -i -e '/^title\s/ { \| ('"$ROOTFS"')$|! s|$| ('"$ROOTFS"')|; }' \
"$LOADER_ENTRY"
END
chmod +x /mnt/etc/kernel/install.d/91-loaderentry-update-title.install
# copy the hostid from the Fedora Linux live environment so ZFS doesn’t complain about being mounted on a different system
cp /etc/hostid /mnt/etc
# install ZFS on the new OS
find ~/zfs-release \
| grep "zfs-release-[0-9]\+-[0-9]\+.fc${VERSION_ID:?}.noarch.rpm" \
| sort | tail -n 1 | xargs -r dnf "${PARAMS[@]:?}" install
PARAMS+=(--repo=zfs)
dnf "${PARAMS[@]}" install kernel kernel-devel zfs zfs-dracut
sed -i '
1 i timeout 10
/^[#[:space:]]*timeout\s.*$/ d
' /mnt/boot/loader/loader.conf
chroot /mnt efibootmgr -C \
-d /dev/sda1 \
-l /efi/systemd/systemd-bootx64.efi \
-L "SD-BOOT A"
# install systemd-boot on the remaining ESPs (repeat as necessary)
umount /mnt/boot
mkdir /mnt/boot@b
(
IFS=','
mount -o "${MNT_OPTS[*]:?}" /dev/sdb1 /mnt/boot@b
)
mount -o bind /mnt/boot@b /mnt/boot
chroot /mnt bootctl install --graceful --no-variables --esp-path=/boot
KVER=($(ls -v /mnt/lib/modules))
chroot /mnt kernel-install add "${KVER[-1]:?}" "/lib/modules/${KVER[-1]}/vmlinuz"
sed -i '
1 i timeout 10
/^[#[:space:]]*timeout\s.*$/ d
' /mnt/boot/loader/loader.conf
chroot /mnt efibootmgr -C \
-d /dev/sdb1 \
-l /efi/systemd/systemd-bootx64.efi \
-L "SD-BOOT B"
# set the boot order
(
shopt -s lastpipe
efibootmgr | grep '^Boot\S*\sSD-BOOT [A-Z]\s' | cut -c 5-8 | readarray -t BOOTORDER
IFS=','
efibootmgr -o "${BOOTORDER[*]}"
)
# create /etc/fstab
MNT_OPTS+=(
nofail
x-systemd.before=bootbind.service
)
for i in boot@{a,b}; do
(
IFS=','
printf 'PARTLABEL=%s /%s vfat %s 0 0\n' "$i" "$i" "${MNT_OPTS[*]}" >> /mnt/etc/fstab
)
done
# install bootsync to keep the ESP content synchronized
# TODO: look into replacing this with bootupd (but not until sd-boot is supported)
dnf "${PARAMS[@]:?}" install git-core selinux-policy-devel gettext-envsubst rsync
chroot /mnt bash -e <<- 'END'
shopt -s lastpipe
mktemp -p /tmp -d temp.XXX | read REPO
trap "rm -rf '$REPO'" exit
cd "$REPO"
git clone --depth 1 https://github.com/gregory-lee-bartholomew/bootsync.git .
make install
make sepolicy_install
END
# update the OS
PARAMS+=(
--repo=updates
--exclude=kernel\*
)
dnf "${PARAMS[@]}" update
# make sure the SELinux labels are reset on first boot
printf -- '-F' > /mnt/.autorelabel
cat <<- 'END' > "/mnt/etc/dkms/framework.conf.d/override.conf"
post_transaction=""
END
# install a few wrapper scripts to help with updating ZFS
printf -v supplements '%s' \
https://raw.githubusercontent.com \
/gregory-lee-bartholomew/fedora-on-zfs \
/refs/heads/main/supplements
for i in dnf zfs-update kernel-update; do
curl -s "$supplements/$i" > /mnt/usr/local/bin/$i
chmod +x /mnt/usr/local/bin/$i
done
Suggested Next Steps