Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions roles/mysql_8_4/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ MYSQL_CONFIG_DATABASES: []
# priv: 'mydb.*:ALL'
# state: present
# append_privs: no

# MySQL configuration paths
MYSQL_CONFIG_BASEDIR: /usr
MYSQL_CONFIG_DATADIR: /var/lib/mysql
MYSQL_CONFIG_PLUGIN_DIR: /usr/lib/mysql/plugin

### Encryption-at-rest settings ###
# This enables the encryption-at-rest
MYSQL_CONFIG_ENCRYPTION_ENABLED: false
# As a prerequisite for encryption-at-rest, we need to install a
# keyring component or plugin (https://dev.mysql.com/doc/refman/8.4/en/innodb-data-encryption.html#innodb-data-encryption-encryption-prerequisites).
# For now, we support only component_keyring_file (https://dev.mysql.com/doc/refman/8.4/en/keyring-file-component.html)
MYSQL_CONFIG_KEYRING_COMPONENT: component_keyring_file
# This is the path where the keyring files will be stored.
MYSQL_CONFIG_KEYRING_DIR: /var/lib/mysql-keyring
# This enables encryption-at-rest for new tables and logs.
MYSQL_CONFIG_AUTO_ENCRYPTION_ENABLED: true

MYSQL_CONFIG_USERS: []
MYSQL_CONFIG_DEFAULT_ALLOWED_HOSTS: "%"

Expand Down
16 changes: 16 additions & 0 deletions roles/mysql_8_4/tasks/configure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,19 @@
mode: preserve
notify:
- Restart mysql

- name: Configure encryption at rest with component_keyring_file
ansible.builtin.include_tasks: encrypt_component_keyring_file.yml
when:
- MYSQL_CONFIG_ENCRYPTION_ENABLED
- MYSQL_CONFIG_KEYRING_COMPONENT == 'component_keyring_file'

# Render the encryption config file when disabling encryption
- name: Put encryption configuration file (encryption disabled)
ansible.builtin.template:
src: encryption.cnf.j2
dest: "{{ MYSQL_CONFIG_EXTRA_CONFIG_PATH }}/encryption.cnf"
mode: preserve
when: not MYSQL_CONFIG_ENCRYPTION_ENABLED
notify:
- Restart mysql
89 changes: 89 additions & 0 deletions roles/mysql_8_4/tasks/encrypt_component_keyring_file.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
### Encryption-at-rest configuration using component_keyring_file ###

- name: Ensure keyring directory exists
ansible.builtin.file:
path: "{{ MYSQL_CONFIG_KEYRING_DIR }}"
state: directory
owner: mysql
group: mysql
mode: '0700'

- name: Install global manifest to load keyring component early
ansible.builtin.copy:
dest: "{{ MYSQL_CONFIG_BASEDIR }}/sbin/mysqld.my"
owner: mysql
group: mysql
mode: '0644'
content: |
{ "components": "file://component_keyring_file" }

- name: Install component_keyring_file config (JSON)
ansible.builtin.copy:
dest: "{{ MYSQL_CONFIG_PLUGIN_DIR }}/component_keyring_file.cnf"
owner: mysql
group: mysql
mode: '0640'
content: |
{
"path": "{{ MYSQL_CONFIG_KEYRING_DIR }}/keyring",
"read_only": false
}

- name: Put encryption configuration file
ansible.builtin.template:
src: encryption.cnf.j2
dest: "{{ MYSQL_CONFIG_EXTRA_CONFIG_PATH }}/encryption.cnf"
mode: preserve
notify:
- Restart mysql

# We need to adjust AppArmor to allow mysqld to read/write the keyring files
# in /usr/sbin/mysqld.my
- name: Ensure AppArmor local dir exists
ansible.builtin.file:
path: /etc/apparmor.d/local
state: directory
mode: "0755"

# The main apparmor profile for mysqld is in /etc/apparmor.d/usr.sbin.mysqld.
# By default, it includes /etc/apparmor.d/local/usr.sbin.mysqld with the line:
# #include <local/usr.sbin.mysqld>
# We add our custom rules there to avoid modifying the main profile directly.
- name: Install custom rules for mysqld in local include
ansible.builtin.copy:
dest: /etc/apparmor.d/local/usr.sbin.mysqld
mode: "0644"
content: |
# Keyring/manifest permissions
/usr/sbin/mysqld.my r,

- name: Reload AppArmor
ansible.builtin.service:
name: apparmor
state: reloaded

- name: Flush all notified handlers now
ansible.builtin.meta: flush_handlers

- name: Check current encryption state of mysql tablespace
ansible.builtin.shell: |
mysql -e "
SELECT COALESCE(
(SELECT ENCRYPTION
FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
WHERE NAME='mysql' LIMIT 1),
'N'
) AS enc;
"
register: mysql_ts_enc
changed_when: false # This task does not change the system state
when: MYSQL_CONFIG_AUTO_ENCRYPTION_ENABLED

- name: Encrypt mysql system tablespace if needed
ansible.builtin.shell: |
mysql -e "
ALTER TABLESPACE mysql ENCRYPTION='Y';
"
when:
- MYSQL_CONFIG_AUTO_ENCRYPTION_ENABLED
- mysql_ts_enc.stdout.find('N') != -1
9 changes: 9 additions & 0 deletions roles/mysql_8_4/templates/encryption.cnf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[mysqld]
# Default encrypt new tables
table_encryption_privilege_check=ON
{% if MYSQL_CONFIG_ENCRYPTION_ENABLED and MYSQL_CONFIG_AUTO_ENCRYPTION_ENABLED %}
default_table_encryption=ON
# Logs at rest
innodb_redo_log_encrypt=ON
innodb_undo_log_encrypt=ON
{% endif %}
5 changes: 3 additions & 2 deletions roles/mysql_8_4/templates/mysqld.cnf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = {{ MYSQL_CONFIG_PORT }}
basedir = /usr
datadir = /var/lib/mysql
basedir = {{ MYSQL_CONFIG_BASEDIR }}
datadir = {{ MYSQL_CONFIG_DATADIR }}
plugin_dir = {{ MYSQL_CONFIG_PLUGIN_DIR }}
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
Expand Down