--- - name: Configure sbctl Secure Boot block: - name: Create Secure Boot signing keys ansible.builtin.command: "{{ chroot_command }} sbctl create-keys" register: _sbctl_create_keys changed_when: _sbctl_create_keys.rc == 0 failed_when: - _sbctl_create_keys.rc != 0 - "'already exists' not in (_sbctl_create_keys.stderr | default(''))" - name: Enroll Secure Boot keys in firmware ansible.builtin.command: "{{ chroot_command }} sbctl enroll-keys --microsoft" register: _sbctl_enroll changed_when: _sbctl_enroll.rc == 0 failed_when: false - name: Install first-boot enrollment service if chroot enrollment failed when: _sbctl_enroll.rc | default(1) != 0 block: - name: Create first-boot sbctl enrollment service ansible.builtin.copy: dest: /mnt/etc/systemd/system/sbctl-enroll.service mode: "0644" content: | [Unit] Description=Enroll Secure Boot keys via sbctl ConditionPathExists=!/var/lib/sbctl/.enrolled After=local-fs.target [Service] Type=oneshot ExecStart=/usr/bin/sbctl enroll-keys --microsoft ExecStartPost=/usr/bin/touch /var/lib/sbctl/.enrolled RemainAfterExit=yes [Install] WantedBy=multi-user.target - name: Enable first-boot enrollment service ansible.builtin.command: "{{ chroot_command }} systemctl enable sbctl-enroll.service" register: _sbctl_service_enable changed_when: _sbctl_service_enable.rc == 0 - name: Find kernel images to sign ansible.builtin.find: paths: /mnt/boot patterns: "vmlinuz-*" file_type: file register: _sbctl_kernel_images - name: Sign kernel images ansible.builtin.command: >- {{ chroot_command }} sbctl sign -s {{ item.path | regex_replace('^/mnt', '') }} loop: "{{ _sbctl_kernel_images.files }}" loop_control: label: "{{ item.path | basename }}" register: _sbctl_sign_kernel changed_when: _sbctl_sign_kernel.rc == 0 failed_when: false - name: Sign GRUB EFI binary vars: _grub_efi_path: "{{ partitioning_efi_mountpoint }}/EFI/archlinux/grubx64.efi" ansible.builtin.command: >- {{ chroot_command }} sbctl sign -s {{ _grub_efi_path }} register: _sbctl_sign_grub changed_when: _sbctl_sign_grub.rc == 0 failed_when: false - name: Ensure pacman hooks directory exists ansible.builtin.file: path: /mnt/etc/pacman.d/hooks state: directory mode: "0755" - name: Install sbctl auto-signing pacman hook ansible.builtin.copy: dest: /mnt/etc/pacman.d/hooks/99-sbctl-sign.hook mode: "0644" content: | [Trigger] Operation = Install Operation = Upgrade Type = Path Target = boot/vmlinuz-* Target = usr/lib/modules/*/vmlinuz [Action] Description = Signing kernel images for Secure Boot... When = PostTransaction Exec = /usr/bin/sbctl sign-all Depends = sbctl - name: Verify sbctl signing status ansible.builtin.command: "{{ chroot_command }} sbctl verify" register: _sbctl_verify changed_when: false failed_when: false - name: Report sbctl Secure Boot status ansible.builtin.debug: msg: >- Secure Boot (sbctl): Enrollment={{ 'done' if (_sbctl_enroll.rc | default(1)) == 0 else 'deferred to first boot' }}. {{ _sbctl_verify.stdout | default('Verify not available') }} rescue: - name: Secure Boot setup failed ansible.builtin.debug: msg: >- sbctl Secure Boot setup failed. On VMs make sure the OVMF firmware is in Setup Mode (fresh NVRAM). On bare metal enter the firmware setup and switch to Setup Mode first. To recover manually: sbctl create-keys && sbctl enroll-keys --microsoft && sbctl sign-all