As @AndrewLowther pointed out in the answer his comment points to:
Officially, you can't create a single storage config that supports
both BIOS and UEFI. The grub_device settings are incompatible.
So you have two options:
- Modify your
user-data with the workaround Andrew suggested
- Create separate
user-data files. One for BIOS and one for UEFI
I'll outline the first option below, which is what you want. This means it'll work for either a BIOS or UEFI computer.
First off, your user-data file supplied is missing #cloud-config as the first line as well as the identity section. Both are required, so I added them in the example below. The identity section is defined with a default username of ubuntu and password of ubuntu. Furthermore, the encrypted drive is configured with a password of ubuntu. Change accordingly.
There are several things with the user-data file below that are different than yours.
grub_device: true is set for the disk instead of grub_device: false
- type: disk
id: disk-mmcblk0
ptable: gpt
match:
size: largest
preserve: false
name: ''
grub_device: true
wipe: superblock-recursive
A small un-formatted partition with flag: bios_grub is added.
- type: partition
id: partition-0
device: disk-mmcblk0
size: 4194304
wipe: superblock
flag: bios_grub
number: 1
preserve: false
grub_device: false
From the curtin documentation regarding bios_grub:
If the host system for curtin has been booted using UEFI then curtin
will install grub to the esp partition. If the system installation
media has been booted using an MBR, grub will be installed onto the
disk’s MBR. However, on a disk with a gpt partition table, there is
not enough space after the MBR for grub to store its second stage
core.img, so a small un-formatted partition with the bios_grub flag is
needed. This partition should be placed at the beginning of the disk
and should be 1MB in size. It should not contain a filesystem or be
mounted anywhere on the system.
grub_device: false is set for all partitions with the exception of the ESP partition used by an UEFI installion. For this partition, grub_device: UEFI is set instead. This is really just a place-holder at the moment and will be edited with early-commands, as outlined next.
- type: partition
id: partition-1
device: disk-mmcblk0
size: 111149056
wipe: superblock
flag: boot
number: 2
preserve: false
grub_device: UEFI
The use of early-commands in the user-data file will modify the autoinstall.yaml file based on whether the computer is UEFI or BIOS. This will modify the grub_device: UEFI setting defined above.
Take a look at the following:
early-commands:
- |
if [ -e "/sys/firmware/efi" ]; then
sed -i -e "s/grub_device: UEFI/grub_device: true/" /autoinstall.yaml
else
sed -i -e "s/grub_device: UEFI/grub_device: false/" /autoinstall.yaml
fi
What this is doing is editing the autoinstall.yaml file based on a conditional. From what I understand, the autoinstall.yaml file is created during the installation and resides in the root directory of the Live Installation. This is a combination of your user-data file and the default autoinstall unanswered/unconfigured questions that the installer fills in.
This checks if the file /sys/firmware/efi exists:
if [ -e "/sys/firmware/efi" ]; then
If true:
Indicates the system is UEFI
Replaces grub_device: UEFI with grub_device: true using sed:
sed -i -e "s/grub_device: UEFI/grub_device: true/" /autoinstall.yaml
Otherwise:
Indicates the system is BIOS
Replaces grub_device: UEFI with grub_device: false using sed:
sed -i -e "s/grub_device: UEFI/grub_device: false/" /autoinstall.yaml
And that's it. After the early-commands are run, the installation will continue.
Here's the complete user-data file:
#cloud-config
autoinstall:
version: 1
identity:
hostname: ubuntu-server
password: $6$5lpwCLsKLEzMkSJc$keOAhA6aO/5RocGThmhVA7LSNuW911Rx5HHXFEa75oGK20cEdAAgn14H5f5nGeq6QgcSyLPrWcg1.JvjXbhrN/
realname: Ubuntu User
username: ubuntu
storage:
config:
- type: disk
id: disk-mmcblk0
ptable: gpt
match:
size: largest
preserve: false
name: ''
grub_device: true
wipe: superblock-recursive
- type: partition
id: partition-0
device: disk-mmcblk0
size: 4194304
wipe: superblock
flag: bios_grub
number: 1
preserve: false
grub_device: false
- type: partition
id: partition-1
device: disk-mmcblk0
size: 111149056
wipe: superblock
flag: boot
number: 2
preserve: false
grub_device: UEFI
- type: format
id: format-0
volume: partition-1
fstype: fat32
preserve: false
- type: partition
id: partition-2
device: disk-mmcblk0
size: 5GB
wipe: superblock
number: 3
preserve: false
grub_device: false
- type: format
id: format-1
volume: partition-2
fstype: ext4
preserve: false
- type: partition
id: partition-3
device: disk-mmcblk0
size: -1
wipe: superblock
number: 4
preserve: false
grub_device: false
- type: dm_crypt
id: dm_crypt-0
volume: partition-3
preserve: false
key: 'ubuntu'
- type: lvm_volgroup
id: lvm_volgroup-0
devices:
- dm_crypt-0
preserve: false
name: ubuntu-vg
- type: lvm_partition
id: lvm_partition-0
volgroup: lvm_volgroup-0
size: -1
preserve: false
wipe: superblock
name: ubuntu-lv
- type: format
id: format-2
volume: lvm_partition-0
fstype: btrfs
preserve: false
- type: mount
id: mount-0
device: format-0
path: /boot/efi
- type: mount
id: mount-1
device: format-1
path: /boot
- type: mount
id: mount-2
device: format-2
path: /
early-commands:
- |
if [ -e "/sys/firmware/efi" ]; then
sed -i -e "s/grub_device: UEFI/grub_device: true/" /autoinstall.yaml
else
sed -i -e "s/grub_device: UEFI/grub_device: false/" /autoinstall.yaml
fi
If you install on both a UEFI and BIOS computer and then compare, you'll notice that the partition scheme will be the same. The UEFI installation will have an unused bios_grub partition, and the BIOS installation will have an unused ESP partition mounted at /boot/efi. The /boot/efi will be empty in a BIOS installation and will have files in an UEFI installation.
The following installations were done with ISO: ubuntu-22.04.3-live-server-amd64.iso. This was unpacked with the above user-data file added to /nocloud and then re-packed.
EFI installation:
$ sudo parted /dev/sda
GNU Parted 3.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 26.8GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 5243kB 4194kB bios_grub
2 5243kB 116MB 111MB fat32 boot, esp
3 116MB 5485MB 5369MB ext4
4 5485MB 26.8GB 21.4GB
$ lsblk -o name,fssize,fsused,fsavail,fstype,mountpoint
NAME FSSIZE FSUSED FSAVAIL FSTYPE MOUNTPOINT
loop0 53.4M 53.4M 0 squashfs /snap/snapd/19457
loop1 112M 112M 0 squashfs /snap/lxd/24322
loop2 63.5M 63.5M 0 squashfs /snap/core20/1974
sda
├─sda1
├─sda2 104.3M 6M 98.3M vfat /boot/efi
├─sda3 4.8G 129.6M 4.4G ext4 /boot
└─sda4 crypto_LUKS
└─dm_crypt-0 LVM2_member
└─ubuntu--vg-ubuntu--lv 19.9G 3G 16G btrfs /
$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 491M 1.1M 490M 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 20G 3.0G 17G 16% /
tmpfs 2.4G 0 2.4G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda3 4.9G 130M 4.5G 3% /boot
/dev/sda2 105M 6.1M 99M 6% /boot/efi
tmpfs 491M 4.0K 491M 1% /run/user/1000
$ ls /boot/efi
EFI
BIOS installation:
$ sudo parted /dev/sda
GNU Parted 3.4
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print
Model: ATA VBOX HARDDISK (scsi)
Disk /dev/sda: 26.8GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 5243kB 4194kB bios_grub
2 5243kB 116MB 111MB fat32 boot, esp
3 116MB 5485MB 5369MB ext4
4 5485MB 26.8GB 21.4GB
$ lsblk -o name,fssize,fsused,fsavail,fstype,mountpoint
NAME FSSIZE FSUSED FSAVAIL FSTYPE MOUNTPOINT
loop0 63.5M 63.5M 0 squashfs /snap/core20/1974
loop1 53.4M 53.4M 0 squashfs /snap/snapd/19457
loop2 112M 112M 0 squashfs /snap/lxd/24322
sda
├─sda1
├─sda2 104.3M 512B 104.3M vfat /boot/efi
├─sda3 4.8G 128.6M 4.4G ext4 /boot
└─sda4 crypto_LUKS
└─dm_crypt-0 LVM2_member
└─ubuntu--vg-ubuntu--lv 19.9G 3G 16G btrfs /
$ df -h
Filesystem Size Used Avail Use% Mounted on
tmpfs 492M 1.1M 491M 1% /run
/dev/mapper/ubuntu--vg-ubuntu--lv 20G 3.0G 17G 16% /
tmpfs 2.4G 0 2.4G 0% /dev/shm
tmpfs 5.0M 0 5.0M 0% /run/lock
/dev/sda3 4.9G 129M 4.5G 3% /boot
/dev/sda2 105M 512 105M 1% /boot/efi
tmpfs 492M 4.0K 492M 1% /run/user/1000
$ ls /boot/efi