prole/infrastructure/roles/mariadb_primary/tasks/main.yml
chrisfu 125da5669b Fix k3s CNPG image registry resolution and import flows
- In k3s mode, resolve CNPG images to a cluster-reachable internal registry and ignore k3d/localhost-ish registry values.

- Avoid any k3d cluster/containerd interactions when PROLE_MODE=k3s; add a preflight-image action.

- Extend init scripts and Ansible k3s/mariadb import tasks/playbooks for the updated k3s flow.

- Add/extend installer UI + tests around services and action/milestone helpers.

- Add merlin MariaDB provisioning playbook, services init-script test, and a k3s datastore SQL snapshot.

Co-authored-by: Junie <junie@jetbrains.com>
2026-03-07 00:23:00 -08:00

148 lines
5.4 KiB
YAML

---
- 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