--- - name: Install MariaDB and tooling ansible.builtin.package: name: - mariadb-server - mariadb-client - rsync state: present - name: Ensure USB mountpoint directory exists ansible.builtin.file: path: "{{ mariadb_usb_mountpoint | default('/srv/mariadb') }}" state: directory owner: root group: root mode: "0755" - name: Mount MariaDB USB filesystem ansible.builtin.mount: src: "LABEL={{ mariadb_usb_label | default('MARIADB') }}" path: "{{ mariadb_usb_mountpoint | default('/srv/mariadb') }}" fstype: "{{ mariadb_usb_fstype | default('ext4') }}" opts: "{{ mariadb_usb_mount_opts | default('noatime,nofail') }}" state: mounted - name: Stop MariaDB before datadir changes ansible.builtin.service: name: mariadb state: stopped failed_when: false - name: Ensure MariaDB datadir exists on USB ansible.builtin.file: path: "{{ mariadb_datadir | default((mariadb_usb_mountpoint | default('/srv/mariadb')) ~ '/mariadb') }}" state: directory owner: mysql group: mysql mode: "0700" - name: Allow MariaDB datadir in AppArmor (Ubuntu/Debian) ansible.builtin.copy: dest: /etc/apparmor.d/local/usr.sbin.mysqld owner: root group: root mode: "0644" content: | # Managed by Ansible (mariadb_primary) {{ mariadb_datadir | default((mariadb_usb_mountpoint | default('/srv/mariadb')) ~ '/mariadb') }}/ r, {{ mariadb_datadir | default((mariadb_usb_mountpoint | default('/srv/mariadb')) ~ '/mariadb') }}/** rwk, register: _mariadb_apparmor_local when: ansible_facts['os_family'] | default('') == 'Debian' - name: Reload AppArmor profile for mysqld ansible.builtin.command: apparmor_parser -r /etc/apparmor.d/usr.sbin.mysqld changed_when: false when: - ansible_facts['os_family'] | default('') == 'Debian' - _mariadb_apparmor_local is changed failed_when: false - name: Configure MariaDB bind-address ansible.builtin.lineinfile: path: /etc/mysql/mariadb.conf.d/50-server.cnf regexp: '^bind-address\s*=' line: "bind-address = {{ mariadb_bind_address | default('0.0.0.0') }}" insertafter: '^\[mysqld\]' register: _mariadb_cfg_bind - name: Configure MariaDB datadir ansible.builtin.lineinfile: path: /etc/mysql/mariadb.conf.d/50-server.cnf regexp: '^datadir\s*=' line: "datadir = {{ mariadb_datadir | default((mariadb_usb_mountpoint | default('/srv/mariadb')) ~ '/mariadb') }}" insertafter: '^\[mysqld\]' register: _mariadb_cfg_datadir - name: Check if source MariaDB system tables exist ansible.builtin.stat: path: /var/lib/mysql/mysql register: _mariadb_src_tables - name: Check if destination MariaDB system tables exist ansible.builtin.stat: path: "{{ (mariadb_datadir | default((mariadb_usb_mountpoint | default('/srv/mariadb')) ~ '/mariadb')) ~ '/mysql' }}" register: _mariadb_dst_tables - name: Copy initial MariaDB data to USB datadir (first migration only) ansible.builtin.command: >- rsync -aHAX --numeric-ids /var/lib/mysql/ {{ mariadb_datadir | default((mariadb_usb_mountpoint | default('/srv/mariadb')) ~ '/mariadb') }}/ when: - _mariadb_src_tables.stat.exists - not _mariadb_dst_tables.stat.exists register: _mariadb_rsync changed_when: true - name: Ensure MariaDB datadir ownership after migration ansible.builtin.command: >- chown -R mysql:mysql {{ mariadb_datadir | default((mariadb_usb_mountpoint | default('/srv/mariadb')) ~ '/mariadb') }} when: - _mariadb_rsync is defined - _mariadb_rsync is changed changed_when: true - name: Ensure MariaDB service is started and enabled ansible.builtin.service: name: mariadb state: started enabled: true - name: Require MariaDB admin credentials ansible.builtin.assert: that: - k3s_mariadb_admin_user | default('') | length > 0 - k3s_mariadb_admin_password | default('') | length > 0 fail_msg: "Set k3s_mariadb_admin_user and vaulted k3s_mariadb_admin_password for MariaDB provisioning." when: not ansible_check_mode - name: Create/ensure MariaDB admin user for remote TCP management ansible.builtin.command: >- mysql --protocol=socket --user=root --execute=" CREATE USER IF NOT EXISTS '{{ k3s_mariadb_admin_user }}'@'%' IDENTIFIED BY '{{ k3s_mariadb_admin_password }}'; ALTER USER '{{ k3s_mariadb_admin_user }}'@'%' IDENTIFIED BY '{{ k3s_mariadb_admin_password }}'; GRANT ALL PRIVILEGES ON *.* TO '{{ k3s_mariadb_admin_user }}'@'%' WITH GRANT OPTION; FLUSH PRIVILEGES;" when: not ansible_check_mode no_log: true - name: Require k3s MariaDB user password (vaulted) ansible.builtin.assert: that: - k3s_datastore_mariadb_password | default('') | length > 0 fail_msg: "k3s_datastore_mariadb_password is empty; set it from Ansible Vault." when: not ansible_check_mode - name: Create k3s database/user/grants (local socket) ansible.builtin.command: >- mysql --protocol=socket --user=root --execute=" CREATE DATABASE IF NOT EXISTS `{{ k3s_datastore_mariadb_db | default('k3s') }}`; CREATE USER IF NOT EXISTS '{{ k3s_datastore_mariadb_user | default('prole_k3s') }}'@'%' IDENTIFIED BY '{{ k3s_datastore_mariadb_password }}'; ALTER USER '{{ k3s_datastore_mariadb_user | default('prole_k3s') }}'@'%' IDENTIFIED BY '{{ k3s_datastore_mariadb_password }}'; GRANT ALL PRIVILEGES ON `{{ k3s_datastore_mariadb_db | default('k3s') }}`.* TO '{{ k3s_datastore_mariadb_user | default('prole_k3s') }}'@'%'; FLUSH PRIVILEGES;" when: not ansible_check_mode no_log: true