Ansible LUKS: Automated Full-Disk Encryption with Ansible
Contents
Ansible LUKS: Automated Full-Disk Encryption with Ansible
ansible.luks automates LUKS (Linux Unified Key Setup) disk encryption operations across Linux hosts using Ansible. It covers creating encrypted volumes, managing keys, and automating unlock at boot.
What is LUKS?
LUKS is the standard Linux disk encryption layer. It provides full-disk or partition-level encryption with support for multiple key slots, making it suitable for both workstations and servers.
Playbook: Encrypting a New Volume
---
- name: Setup LUKS encrypted volume
hosts: storage_nodes
become: true
vars:
luks_device: /dev/sdb
luks_name: data_encrypted
luks_mount: /mnt/data
luks_fs: ext4
tasks:
- name: Install cryptsetup
package:
name: cryptsetup
state: present
- name: Check if device is already LUKS-formatted
command: cryptsetup isLuks {{ luks_device }}
register: is_luks
failed_when: false
changed_when: false
- name: Format device with LUKS
expect:
command: cryptsetup luksFormat {{ luks_device }}
responses:
"Are you sure.*": "YES"
"Enter passphrase.*": "{{ luks_passphrase }}"
"Verify passphrase.*": "{{ luks_passphrase }}"
when: is_luks.rc != 0
no_log: true
- name: Open LUKS device
expect:
command: cryptsetup open {{ luks_device }} {{ luks_name }}
responses:
"Enter passphrase.*": "{{ luks_passphrase }}"
when: is_luks.rc != 0
no_log: true
- name: Create filesystem
filesystem:
fstype: "{{ luks_fs }}"
dev: "/dev/mapper/{{ luks_name }}"
when: is_luks.rc != 0
- name: Create mount point
file:
path: "{{ luks_mount }}"
state: directory
mode: "0755"
- name: Mount encrypted volume
mount:
path: "{{ luks_mount }}"
src: "/dev/mapper/{{ luks_name }}"
fstype: "{{ luks_fs }}"
state: mountedKey Management Role
# roles/luks_keys/tasks/main.yml
---
- name: Add a new LUKS key slot
command: >
cryptsetup luksAddKey {{ luks_device }}
--key-file <(echo -n "{{ existing_passphrase }}")
args:
stdin: "{{ new_passphrase }}"
no_log: true
- name: Remove a LUKS key slot
command: >
cryptsetup luksRemoveKey {{ luks_device }}
args:
stdin: "{{ passphrase_to_remove }}"
no_log: true
- name: Check key slots usage
command: cryptsetup luksDump {{ luks_device }}
register: luks_dump
changed_when: false
- name: Show key slots
debug:
msg: "{{ luks_dump.stdout | regex_findall('Key Slot \\d+: ENABLED') }}"Auto-unlock with a Keyfile (Server Use)
- name: Create keyfile for auto-unlock
copy:
content: "{{ luks_keyfile_content }}"
dest: /etc/luks-keys/data.key
mode: "0400"
owner: root
no_log: true
- name: Add keyfile as LUKS key slot
command: >
cryptsetup luksAddKey {{ luks_device }} /etc/luks-keys/data.key
args:
stdin: "{{ luks_passphrase }}"
no_log: true
- name: Configure crypttab for auto-unlock
lineinfile:
path: /etc/crypttab
line: "{{ luks_name }} {{ luks_device }} /etc/luks-keys/data.key luks"
create: trueInventory Example
[storage_nodes]
node1 ansible_host=192.168.1.10
node2 ansible_host=192.168.1.11
node3 ansible_host=192.168.1.12# group_vars/storage_nodes/vault.yml (ansible-vault encrypted)
luks_passphrase: !vault |
$ANSIBLE_VAULT;1.1;AES256
...Running the Playbook
# Encrypt a new volume (passphrase from vault)
ansible-playbook -i inventory setup-luks.yml --ask-vault-pass
# Rotate keys
ansible-playbook -i inventory rotate-keys.yml --ask-vault-passConclusion
Automating LUKS with Ansible makes full-disk encryption manageable at scale. Combined with ansible-vault for secret management, this playbook provides a repeatable, auditable approach to securing data at rest across Linux infrastructure.
Source: GitHub