--- - name: Configure disk encryption when: partitioning_luks_enabled | default(luks_enabled | default(false)) | bool vars: configuration_luks_passphrase_effective: >- {{ (partitioning_luks_passphrase | default(luks_passphrase | default(''))) | string }} block: - name: Set LUKS configuration facts vars: configuration_luks_mapper_name_value: >- {{ partitioning_luks_mapper_name | default(luks_mapper_name | default('SYSTEM_DECRYPTED')) }} configuration_luks_device_value: >- {{ partitioning_luks_device | default( install_drive ~ ( partitioning_root_partition_suffix | default(partitioning_main_partition_suffix | default(2)) | string ) ) }} configuration_luks_tpm2_pcrs_raw: >- {{ partitioning_luks_tpm2_pcrs | default(luks_tpm2_pcrs | default('')) }} configuration_luks_tpm2_pcrs_effective_value: >- {{ ( configuration_luks_tpm2_pcrs_raw if configuration_luks_tpm2_pcrs_raw is string else (configuration_luks_tpm2_pcrs_raw | map('string') | join('+')) ) | string | replace(',', '+') | regex_replace('\\s+', '') | regex_replace('^\\+|\\+$', '') }} ansible.builtin.set_fact: configuration_luks_mapper_name: "{{ configuration_luks_mapper_name_value }}" configuration_luks_uuid: "{{ partitioning_luks_uuid | default('') }}" configuration_luks_device: "{{ configuration_luks_device_value }}" configuration_luks_options: >- {{ partitioning_luks_options | default(luks_options | default('discard,tries=3')) }} configuration_luks_auto_method: >- {{ (partitioning_luks_auto_decrypt | default(luks_auto_decrypt | default(true)) | bool) | ternary( partitioning_luks_auto_decrypt_method | default(luks_auto_decrypt_method | default('tpm2')), 'manual' ) }} configuration_luks_tpm2_device: >- {{ partitioning_luks_tpm2_device | default(luks_tpm2_device | default('auto')) }} configuration_luks_tpm2_pcrs: "{{ configuration_luks_tpm2_pcrs_raw }}" configuration_luks_tpm2_pcrs_effective: "{{ configuration_luks_tpm2_pcrs_effective_value }}" configuration_luks_keyfile_path: >- /etc/cryptsetup-keys.d/{{ configuration_luks_mapper_name_value }}.key changed_when: false - name: Validate LUKS UUID is available ansible.builtin.assert: that: - configuration_luks_uuid | length > 0 fail_msg: LUKS UUID not available. Ensure partitioning ran before configuration. - name: Validate LUKS passphrase for auto-decrypt when: configuration_luks_auto_method in ['tpm2', 'keyfile'] ansible.builtin.assert: that: - configuration_luks_passphrase_effective | length > 0 fail_msg: luks_passphrase (or partitioning_luks_passphrase) must be set for LUKS auto-decrypt. no_log: true - name: Enroll TPM2 for LUKS when: configuration_luks_auto_method == 'tpm2' ansible.builtin.include_tasks: encryption/tpm2.yml - name: Configure LUKS keyfile auto-decrypt when: configuration_luks_auto_method == 'keyfile' ansible.builtin.include_tasks: encryption/keyfile.yml - name: Build LUKS parameters vars: configuration_luks_keyfile_in_use_value: "{{ configuration_luks_auto_method == 'keyfile' }}" configuration_luks_option_list_value: >- {{ (configuration_luks_options | trim).split(',') if configuration_luks_options | trim | length > 0 else [] }} configuration_luks_tpm2_option_list_value: >- {{ (configuration_luks_auto_method == 'tpm2') | ternary( ['tpm2-device=' + configuration_luks_tpm2_device] + (['tpm2-pcrs=' + configuration_luks_tpm2_pcrs_effective] if configuration_luks_tpm2_pcrs_effective | length > 0 else []), [] ) }} configuration_luks_crypttab_keyfile_value: >- {{ configuration_luks_keyfile_path if configuration_luks_keyfile_in_use_value else 'none' }} configuration_luks_crypttab_options_value: >- {{ (['luks'] + configuration_luks_option_list_value + configuration_luks_tpm2_option_list_value) | join(',') }} configuration_luks_rd_options_value: >- {{ (configuration_luks_option_list_value + configuration_luks_tpm2_option_list_value) | join(',') }} configuration_luks_kernel_args_value: >- {{ ( ['rd.luks.name=' + configuration_luks_uuid + '=' + configuration_luks_mapper_name] + ( ['rd.luks.options=' + configuration_luks_uuid + '=' + configuration_luks_rd_options_value] if configuration_luks_rd_options_value | length > 0 else [] ) + ( ['rd.luks.key=' + configuration_luks_uuid + '=' + configuration_luks_keyfile_path] if configuration_luks_keyfile_in_use_value else [] ) ) | join(' ') }} ansible.builtin.set_fact: configuration_luks_keyfile_in_use: "{{ configuration_luks_keyfile_in_use_value }}" configuration_luks_option_list: "{{ configuration_luks_option_list_value }}" configuration_luks_tpm2_option_list: "{{ configuration_luks_tpm2_option_list_value }}" configuration_luks_crypttab_keyfile: "{{ configuration_luks_crypttab_keyfile_value }}" configuration_luks_crypttab_options: "{{ configuration_luks_crypttab_options_value }}" configuration_luks_rd_options: "{{ configuration_luks_rd_options_value }}" configuration_luks_kernel_args: "{{ configuration_luks_kernel_args_value }}" - name: Remove LUKS keyfile if TPM2 auto-decrypt is active when: configuration_luks_auto_method == 'tpm2' ansible.builtin.file: path: /mnt{{ configuration_luks_keyfile_path }} state: absent - name: Write crypttab entry ansible.builtin.lineinfile: path: /mnt/etc/crypttab regexp: "^{{ configuration_luks_mapper_name }}\\s" line: >- {{ configuration_luks_mapper_name }} UUID={{ configuration_luks_uuid }} {{ configuration_luks_crypttab_keyfile }} {{ configuration_luks_crypttab_options }} create: true mode: "0600" - name: Ensure keyfile pattern for initramfs-tools when: - is_debian | default(false) - configuration_luks_keyfile_in_use ansible.builtin.lineinfile: path: /mnt/etc/cryptsetup-initramfs/conf-hook regexp: '^KEYFILE_PATTERN=' line: 'KEYFILE_PATTERN=/etc/cryptsetup-keys.d/*.key' create: true mode: "0644" - name: Configure mkinitcpio hooks for LUKS when: os | lower == 'archlinux' ansible.builtin.lineinfile: path: /mnt/etc/mkinitcpio.conf regexp: '^HOOKS=' line: >- HOOKS=(base systemd autodetect microcode modconf kms keyboard sd-vconsole block sd-encrypt lvm2 filesystems fsck) - name: Read mkinitcpio configuration when: os | lower == 'archlinux' ansible.builtin.slurp: src: /mnt/etc/mkinitcpio.conf register: configuration_mkinitcpio_slurp - name: Build mkinitcpio FILES list when: os | lower == 'archlinux' vars: configuration_mkinitcpio_files_list_value: >- {{ ( configuration_mkinitcpio_slurp.content | b64decode | regex_findall('^FILES=\\(([^)]*)\\)', multiline=True) | default([]) | first | default('') ).split() }} configuration_mkinitcpio_files_list_new_value: >- {{ ( (configuration_mkinitcpio_files_list_value + [configuration_luks_keyfile_path]) if configuration_luks_keyfile_in_use else ( configuration_mkinitcpio_files_list_value | reject('equalto', configuration_luks_keyfile_path) | list ) ) | unique }} ansible.builtin.set_fact: configuration_mkinitcpio_files_list_new: "{{ configuration_mkinitcpio_files_list_new_value }}" - name: Configure mkinitcpio FILES list when: os | lower == 'archlinux' ansible.builtin.lineinfile: path: /mnt/etc/mkinitcpio.conf regexp: '^FILES=' line: >- FILES=({{ configuration_mkinitcpio_files_list_new | join(' ') }}) - name: Ensure dracut config directory exists when: is_rhel | default(false) ansible.builtin.file: path: /mnt/etc/dracut.conf.d state: directory mode: "0755" - name: Configure dracut for LUKS when: is_rhel | default(false) ansible.builtin.copy: dest: /mnt/etc/dracut.conf.d/crypt.conf content: | add_dracutmodules+=" crypt " {% if configuration_luks_keyfile_in_use %} install_items+=" {{ configuration_luks_keyfile_path }} " {% endif %} mode: "0644" - name: Read kernel cmdline defaults when: is_rhel | default(false) ansible.builtin.slurp: src: /mnt/etc/kernel/cmdline register: configuration_kernel_cmdline_slurp - name: Build kernel cmdline with LUKS args when: is_rhel | default(false) vars: configuration_kernel_cmdline_current_value: >- {{ configuration_kernel_cmdline_slurp.content | b64decode | trim }} configuration_kernel_cmdline_list_value: >- {{ configuration_kernel_cmdline_current_value.split() if configuration_kernel_cmdline_current_value | length > 0 else [] }} configuration_kernel_cmdline_filtered_value: >- {{ configuration_kernel_cmdline_list_value | reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=') | list }} configuration_kernel_cmdline_new_value: >- {{ (configuration_kernel_cmdline_filtered_value + configuration_luks_kernel_args.split()) | unique | join(' ') }} ansible.builtin.set_fact: configuration_kernel_cmdline_new: "{{ configuration_kernel_cmdline_new_value }}" changed_when: false - name: Write kernel cmdline with LUKS args when: is_rhel | default(false) ansible.builtin.copy: dest: /mnt/etc/kernel/cmdline mode: "0644" content: "{{ configuration_kernel_cmdline_new }}\n" - name: Find BLS entries when: is_rhel | default(false) ansible.builtin.find: paths: /mnt/boot/loader/entries patterns: "*.conf" register: configuration_kernel_bls_entries changed_when: false - name: Update BLS options with LUKS args when: - is_rhel | default(false) - configuration_kernel_bls_entries.files | length > 0 ansible.builtin.lineinfile: path: "{{ item.path }}" regexp: '^options ' line: "options {{ configuration_kernel_cmdline_new }}" loop: "{{ configuration_kernel_bls_entries.files }}" loop_control: label: "{{ item.path }}" - name: Read grub defaults when: not is_rhel | default(false) ansible.builtin.slurp: src: /mnt/etc/default/grub register: configuration_grub_slurp - name: Build grub command lines with LUKS args when: not is_rhel | default(false) vars: configuration_grub_content_value: "{{ configuration_grub_slurp.content | b64decode }}" configuration_grub_cmdline_linux_value: >- {{ configuration_grub_content_value | regex_findall('^GRUB_CMDLINE_LINUX=\"(.*)\"', multiline=True) | default([]) | first | default('') }} configuration_grub_cmdline_default_value: >- {{ configuration_grub_content_value | regex_findall('^GRUB_CMDLINE_LINUX_DEFAULT=\"(.*)\"', multiline=True) | default([]) | first | default('') }} configuration_grub_cmdline_linux_list_value: >- {{ configuration_grub_cmdline_linux_value.split() if configuration_grub_cmdline_linux_value | length > 0 else [] }} configuration_grub_cmdline_default_list_value: >- {{ configuration_grub_cmdline_default_value.split() if configuration_grub_cmdline_default_value | length > 0 else [] }} configuration_luks_kernel_args_list_value: "{{ configuration_luks_kernel_args.split() }}" configuration_grub_cmdline_linux_new_value: >- {{ ( ( configuration_grub_cmdline_linux_list_value | reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=') | list ) + configuration_luks_kernel_args_list_value ) | unique | join(' ') }} configuration_grub_cmdline_default_new_value: >- {{ ( ( configuration_grub_cmdline_default_list_value | reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=') | list ) + configuration_luks_kernel_args_list_value ) | unique | join(' ') }} ansible.builtin.set_fact: configuration_grub_content: "{{ configuration_grub_content_value }}" configuration_grub_cmdline_linux: "{{ configuration_grub_cmdline_linux_value }}" configuration_grub_cmdline_default: "{{ configuration_grub_cmdline_default_value }}" configuration_grub_cmdline_linux_new: "{{ configuration_grub_cmdline_linux_new_value }}" configuration_grub_cmdline_default_new: "{{ configuration_grub_cmdline_default_new_value }}" - name: Update GRUB_CMDLINE_LINUX_DEFAULT for LUKS when: not is_rhel | default(false) ansible.builtin.lineinfile: path: /mnt/etc/default/grub regexp: '^GRUB_CMDLINE_LINUX_DEFAULT=' line: 'GRUB_CMDLINE_LINUX_DEFAULT="{{ configuration_grub_cmdline_default_new }}"'