--- - name: Configure disk encryption when: system_cfg.luks.enabled | bool vars: configuration_luks_passphrase: >- {{ system_cfg.luks.passphrase | string }} block: - name: Set LUKS configuration facts vars: luks_tpm2_pcrs: >- {{ ( system_cfg.luks.tpm2.pcrs if system_cfg.luks.tpm2.pcrs is string else (system_cfg.luks.tpm2.pcrs | map('string') | join('+')) ) | string | replace(',', '+') | regex_replace('\\s+', '') | regex_replace('^\\+|\\+$', '') }} ansible.builtin.set_fact: configuration_luks_mapper_name: "{{ system_cfg.luks.mapper }}" configuration_luks_uuid: "{{ partitioning_luks_uuid | default('') }}" configuration_luks_device: "{{ partitioning_luks_device }}" configuration_luks_options: "{{ system_cfg.luks.options }}" configuration_luks_auto_method: >- {{ (system_cfg.luks.auto | bool) | ternary( system_cfg.luks.method, 'manual' ) }} configuration_luks_tpm2_device: "{{ partitioning_luks_tpm2_device }}" configuration_luks_tpm2_pcrs: "{{ luks_tpm2_pcrs }}" configuration_luks_keyfile_path: "/etc/cryptsetup-keys.d/{{ system_cfg.luks.mapper }}.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 | length > 0 fail_msg: system.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: luks_keyfile_in_use: "{{ configuration_luks_auto_method == 'keyfile' }}" luks_option_list: >- {{ (configuration_luks_options | trim).split(',') if configuration_luks_options | trim | length > 0 else [] }} luks_tpm2_option_list: >- {{ (configuration_luks_auto_method == 'tpm2') | ternary( ['tpm2-device=' + configuration_luks_tpm2_device] + (['tpm2-pcrs=' + configuration_luks_tpm2_pcrs] if configuration_luks_tpm2_pcrs | length > 0 else []), [] ) }} luks_crypttab_keyfile: "{{ configuration_luks_keyfile_path if luks_keyfile_in_use else 'none' }}" luks_crypttab_options: >- {{ (['luks'] + luks_option_list + luks_tpm2_option_list) | join(',') }} luks_rd_options: "{{ (luks_option_list + luks_tpm2_option_list) | join(',') }}" luks_kernel_args: >- {{ ( ['rd.luks.name=' + configuration_luks_uuid + '=' + configuration_luks_mapper_name] + ( ['rd.luks.options=' + configuration_luks_uuid + '=' + luks_rd_options] if luks_rd_options | length > 0 else [] ) + ( ['rd.luks.key=' + configuration_luks_uuid + '=' + configuration_luks_keyfile_path] if luks_keyfile_in_use else [] ) ) | join(' ') }} ansible.builtin.set_fact: configuration_luks_keyfile_in_use: "{{ luks_keyfile_in_use }}" configuration_luks_option_list: "{{ luks_option_list }}" configuration_luks_tpm2_option_list: "{{ luks_tpm2_option_list }}" configuration_luks_crypttab_keyfile: "{{ luks_crypttab_keyfile }}" configuration_luks_crypttab_options: "{{ luks_crypttab_options }}" configuration_luks_rd_options: "{{ luks_rd_options }}" configuration_luks_kernel_args: "{{ luks_kernel_args }}" - 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 | bool - 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: mkinitcpio_files_list: >- {{ ( configuration_mkinitcpio_slurp.content | b64decode | regex_findall('^FILES=\\(([^)]*)\\)', multiline=True) | default([]) | first | default('') ).split() }} mkinitcpio_files_list_new: >- {{ ( (mkinitcpio_files_list + [configuration_luks_keyfile_path]) if configuration_luks_keyfile_in_use else ( mkinitcpio_files_list | reject('equalto', configuration_luks_keyfile_path) | list ) ) | unique }} ansible.builtin.set_fact: configuration_mkinitcpio_files_list_new: "{{ mkinitcpio_files_list_new }}" - 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 | bool ansible.builtin.file: path: /mnt/etc/dracut.conf.d state: directory mode: "0755" - name: Configure dracut for LUKS when: is_rhel | bool 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 | bool ansible.builtin.slurp: src: /mnt/etc/kernel/cmdline register: configuration_kernel_cmdline_slurp - name: Build kernel cmdline with LUKS args when: is_rhel | bool vars: kernel_cmdline_current: >- {{ configuration_kernel_cmdline_slurp.content | b64decode | trim }} kernel_cmdline_list: >- {{ kernel_cmdline_current.split() if kernel_cmdline_current | length > 0 else [] }} kernel_cmdline_filtered: >- {{ kernel_cmdline_list | reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=') | list }} kernel_cmdline_new: >- {{ (kernel_cmdline_filtered + configuration_luks_kernel_args.split()) | unique | join(' ') }} ansible.builtin.set_fact: configuration_kernel_cmdline_new: "{{ kernel_cmdline_new }}" changed_when: false - name: Write kernel cmdline with LUKS args when: is_rhel | bool ansible.builtin.copy: dest: /mnt/etc/kernel/cmdline mode: "0644" content: "{{ configuration_kernel_cmdline_new }}\n" - name: Find BLS entries when: is_rhel | bool 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 | bool - 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 | bool ansible.builtin.slurp: src: /mnt/etc/default/grub register: configuration_grub_slurp - name: Build grub command lines with LUKS args when: not is_rhel | bool vars: grub_content: "{{ configuration_grub_slurp.content | b64decode }}" grub_cmdline_linux: >- {{ grub_content | regex_findall('^GRUB_CMDLINE_LINUX=\"(.*)\"', multiline=True) | default([]) | first | default('') }} grub_cmdline_default: >- {{ grub_content | regex_findall('^GRUB_CMDLINE_LINUX_DEFAULT=\"(.*)\"', multiline=True) | default([]) | first | default('') }} grub_cmdline_linux_list: >- {{ grub_cmdline_linux.split() if grub_cmdline_linux | length > 0 else [] }} grub_cmdline_default_list: >- {{ grub_cmdline_default.split() if grub_cmdline_default | length > 0 else [] }} luks_kernel_args_list: "{{ configuration_luks_kernel_args.split() }}" grub_cmdline_linux_new: >- {{ ( ( grub_cmdline_linux_list | reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=') | list ) + luks_kernel_args_list ) | unique | join(' ') }} grub_cmdline_default_new: >- {{ ( ( grub_cmdline_default_list | reject('match', '^rd\\.luks\\.(name|options|key)=' ~ configuration_luks_uuid ~ '=') | list ) + luks_kernel_args_list ) | unique | join(' ') }} ansible.builtin.set_fact: configuration_grub_content: "{{ grub_content }}" configuration_grub_cmdline_linux: "{{ grub_cmdline_linux }}" configuration_grub_cmdline_default: "{{ grub_cmdline_default }}" configuration_grub_cmdline_linux_new: "{{ grub_cmdline_linux_new }}" configuration_grub_cmdline_default_new: "{{ grub_cmdline_default_new }}" - name: Update GRUB_CMDLINE_LINUX_DEFAULT for LUKS when: not is_rhel | bool ansible.builtin.lineinfile: path: /mnt/etc/default/grub regexp: "^GRUB_CMDLINE_LINUX_DEFAULT=" line: 'GRUB_CMDLINE_LINUX_DEFAULT="{{ configuration_grub_cmdline_default_new }}"'