Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: v3.2.0 - firewall support, fixes, improvements #61

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
# Change log

This file contains al notable changes to the mariadb Ansible role.
This file contains all notable changes to the mariadb Ansible role.

This file adheres to the guidelines of <http://keepachangelog.com/>. Versioning follows [Semantic Versioning](http://semver.org/).

## 3.2.0 - 2022-10-15

### Added

- Firewall helpers to open ports on target host using either `ufw` or `iptables` (credit: @nxet)

### Changed

- Add detailed tags to all tasks
- Use static `import_tasks` instead of dynamic `include_` to propagate tags to all children tasks
- Use FQCNs for all tasks
- Fix support for MariaDB mirror URL config option `mariadb_mirror`

## 3.1.3 - 2022-10-14

### Changed
Expand Down
41 changes: 37 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Ansible role `mariadb`

An Ansible role for managing MariaDB in RedHat-based distributions. Specifically, the responsibilities of this role are to:
An Ansible role for managing MariaDB in Debian and RedHat-based distributions. Specifically, the responsibilities of this role are to:

- Install MariaDB packages from the official MariaDB repositories
- Remove unsafe defaults:
Expand All @@ -10,6 +10,7 @@ An Ansible role for managing MariaDB in RedHat-based distributions. Specifically
- Create users and databases
- Manage configuration files `server.cnf` and `custom.cnf`
- Upload SSL certificates and configure the server to use them
- Optionally open firewall ports

Refer to the [change log](CHANGELOG.md) for notable changes in each release.

Expand All @@ -31,14 +32,16 @@ None of the variables below are required. When not defined by the user, the [def
| `mariadb_configure_swappiness` | true | When `true`, this role will set the "swappiness" value (see `mariadb_swappiness`. |
| `mariadb_custom_cnf` | {} | Dictionary with custom configuration. |
| `mariadb_databases` | [] | List of dicts specifying the databases to be added. See below for details. |
| `mariadb_mirror` | yum.mariadb.org | Download mirror for the .rpm package (1) |
| `mariadb_mirror` | null | Download mirror for the rpm/apt package (1) |
| `mariadb_port` | 3306 | The port number used to listen to client requests |
| `mariadb_firewall_backend` | null | Firewall backend used to open ports, the default `null` skips the tasks. |
| `mariadb_allowed_ips` | {'world': 'any'} | Dict of CIDRs to allow incoming connections from. See examples below. |
| `mariadb_root_password` | '' | The MariaDB root password. (2) |
| `mariadb_server_cnf` | {} | Dictionary with server configuration. |
| `mariadb_service` | mariadb | Name of the service (should e.g. be 'mysql' on CentOS for MariaDB 5.5) |
| `mariadb_swappiness` | '0' | "Swappiness" value (string). System default is 60. A value of 0 means that swapping out processes is avoided.|
| `mariadb_users` | [] | List of dicts specifying the users to be added. See below for details. |
| `mariadb_version` | '10.5' | The version of MariaDB to be installed. Default is the current stable release. |
| `mariadb_version` | '10.6' | The version of MariaDB to be installed. Default is the current stable release. |
| `mariadb_ssl_ca_crt` | null | Path to the certificate authority's root certificate |
| `mariadb_ssl_server_crt` | null | Path to the server's SSL certificate |
| `mariadb_ssl_server_key` | null | Path to the server's SSL certificate key |
Expand All @@ -56,6 +59,12 @@ mariadb_mirror: 'mirror.mva-n.net/mariadb/repo'

(2) **It is highly recommended to set the database root password!** Leaving the password empty is a serious security risk. The role will issue a warning if the variable was not set.


### Debian support

The role is tested working on both Debian 10 `buster` and 11 `bullseye`.
Older versions of MariaDB might not work anymore though, and it is recommended to explicitly configure `mariadb_version` in order to target a known compatible release.

### Server configuration

You can specify the configuration in `/etc/my.cnf.d/server.cnf` (in RHEL/Fedora, `/etc/mysql/conf.d/server.cnf` in Debian), specifically in the `[mariadb]` section, by providing a dictionary of keys/values in the variable `mariadb_server_cnf`. Please refer to the [MariaDB Server System Variables documentation](https://mariadb.com/kb/en/mariadb/server-system-variables/) for details on the possible settings.
Expand Down Expand Up @@ -134,9 +143,33 @@ mariadb_users:
host: '192.168.56.%'
```

### Opening firewall port

The role provides tasks to automatically open the firewall port (as configured with `mariadb_port`) used by MariaDB, either with `ufw` or `iptables`. Feel free to [open an Issue](https://github.com/bertvv/ansible-role-mariadb/issues/new)/PR to add support for more firewall backends.
To enable these tasks the `mariadb_firewall_backend` option must be set explicitly to either `ufw` or `iptables`, since the default `null` will simply ignore the tasks.
The config option `mariadb_allowed_ips` is a dictionary of IPs/CIDRs allowed to connect to the daemon.
> NB: the firewall must be already installed on the target host.
The role *will fail trying* instead of checking if the package is available.

An example:

```Yaml
mariadb_firewall_backend: ufw
mariadb_allowed_ips:
admins: 10.0.10.0/24
workers: 10.0.11.0/24
proxy: 192.168.1.100
```

This will create three separate rules which, depending on the backend used, will be along the lines of:
- `allow incoming from 10.0.10.0/24 to 0.0.0.0 port 3306 proto tcp comment 'mariadb-admins'`
- `allow incoming from 10.0.11.0/24 to 0.0.0.0 port 3306 proto tcp comment 'mariadb-workers'`
- `allow incoming from 192.168.1.100 to 0.0.0.0 port 3306 proto tcp comment 'mariadb-proxy'`

## Dependencies

No dependencies.
The collections `community.mysql` and `community.posix` must be installed.
When using the `ufw` firewall tasks, the `community.general` collection must also be present.

## Example Playbook

Expand Down
6 changes: 5 additions & 1 deletion defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ mariadb_users: []
mariadb_root_password: ''
mariadb_auth_unix_plugin: false

mariadb_mirror: yum.mariadb.org
mariadb_mirror: null
mariadb_version: '10.6'

mariadb_configure_swappiness: true
Expand All @@ -29,6 +29,10 @@ mariadb_logrotate:

mariadb_service: mariadb
mariadb_bind_address: '127.0.0.1'
mariadb_port: '3306'
mariadb_firewall_backend: null
mariadb_allowed_ips:
world: any

# Server configuration
mariadb_server_cnf: {}
Expand Down
1 change: 1 addition & 0 deletions meta/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ galaxy_info:
- name: Debian
versions:
- 10
- 11
galaxy_tags:
- database
- sql
Expand Down
47 changes: 22 additions & 25 deletions tasks/add-repo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,35 @@
---

- name: Add official MariaDB repository (yum)
template:
ansible.builtin.template:
src: etc_yum.repos.d_mariadb.repo.j2
dest: /etc/yum.repos.d/MariaDB.repo
mode: '0644'
when: ansible_distribution != 'Debian'
tags: mariadb
tags: mariadb-repo-yum


- name: Install gpg to add repokey (apt)
package:
name: gpg
state: latest
- name: Run Debian-specific tasks
when: ansible_distribution == 'Debian'
tags: mariadb
tags: mariadb-repo-apt
block:

- name: Add official MariaDB repository key (apt)
apt_key:
url: https://mariadb.org/mariadb_release_signing_key.asc
state: present
when: ansible_distribution == 'Debian'
tags: mariadb
- name: Install gpg to add repokey (apt)
ansible.builtin.package:
name: gpg
state: latest

- name: Add official MariaDB repository (apt)
template:
src: etc_apt_sources.list.d_mariadb.list.j2
dest: /etc/apt/sources.list.d/mariadb.list
mode: '0644'
when: ansible_distribution == 'Debian'
tags: mariadb
- name: Add official MariaDB repository key (apt)
ansible.builtin.apt_key:
url: https://mariadb.org/mariadb_release_signing_key.asc
state: present

- name: Update packages cache with new repo (apt)
apt:
update_cache: true
when: ansible_distribution == 'Debian'
tags: mariadb
- name: Add official MariaDB repository (apt)
ansible.builtin.template:
src: etc_apt_sources.list.d_mariadb.list.j2
dest: /etc/apt/sources.list.d/mariadb.list
mode: '0644'

- name: Update packages cache with new repo (apt)
ansible.builtin.apt:
update_cache: true
12 changes: 6 additions & 6 deletions tasks/auth-unix-plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# Shell is unfortunately necessary because the mysql_user module doesn't yet
# support plugin changes.
- name: Enable plugin unix_socket
shell: >
ansible.builtin.shell: >
mysql -S {{ mariadb_socket }} -u root -e
"INSTALL PLUGIN unix_socket SONAME 'auth_socket'"
||
Expand All @@ -15,10 +15,10 @@
- plugin_install_result.rc != 0
- 'already installed' not in plugin_install_result.stderr
no_log: true
tags: mariadb
tags: mariadb-authunix-enable

- name: Check for unix_socket in plugin column
shell: >
ansible.builtin.shell: >
mysql -N -s -S {{ mariadb_socket }} -u root -e
"SELECT plugin from mysql.user WHERE user = 'root'"
||
Expand All @@ -27,10 +27,10 @@
register: plugin_root_result
changed_when: plugin_root_result.stdout is not search('unix_socket')
no_log: true
tags: mariadb
tags: mariadb-authunix-check

- name: Update root user to use unix_socket
shell: >
ansible.builtin.shell: >
mysql -S {{ mariadb_socket }} -u root -e
"UPDATE mysql.user SET plugin = 'unix_socket' WHERE user = 'root';
FLUSH PRIVILEGES;"
Expand All @@ -40,4 +40,4 @@
FLUSH PRIVILEGES;"
when: plugin_root_result.stdout is not search('unix_socket')
no_log: true
tags: mariadb
tags: mariadb-authunix-config
20 changes: 10 additions & 10 deletions tasks/certificates.yml
Original file line number Diff line number Diff line change
@@ -1,43 +1,43 @@
---

- name: Create destination directory
file:
ansible.builtin.file:
path: "{{ mariadb_config_certificates }}"
state: directory
mode: '750'
owner: "{{ mariadb_system_user.uid }}"
group: "{{ mariadb_system_user.gid }}"
tags: mariadb
tags: mariadb-ssl-copy

- name: Copy root certificate
copy:
ansible.builtin.copy:
content: "{{ lookup('file', mariadb_ssl_ca_crt) }}"
dest: "{{ mariadb_config_certificates }}/ca.crt"
mode: '0644'
owner: "{{ mariadb_system_user.uid }}"
group: "{{ mariadb_system_user.gid }}"
tags: mariadb
tags: mariadb-ssl-copy

- name: Copy server's SSL certificate
copy:
ansible.builtin.copy:
content: "{{ lookup('file', mariadb_ssl_server_crt) }}"
dest: "{{ mariadb_config_certificates }}/server.crt"
mode: '0644'
owner: "{{ mariadb_system_user.uid }}"
group: "{{ mariadb_system_user.gid }}"
tags: mariadb
tags: mariadb-ssl-copy

- name: Copy server's SSL certificate key
copy:
ansible.builtin.copy:
content: "{{ lookup('file', mariadb_ssl_server_key) }}"
dest: "{{ mariadb_config_certificates }}/server.key"
mode: '0600'
owner: "{{ mariadb_system_user.uid }}"
group: "{{ mariadb_system_user.gid }}"
tags: mariadb
tags: mariadb-ssl-copy

- name: Add SSL configuration
blockinfile:
ansible.builtin.blockinfile:
path: "{{ mariadb_config_directory }}/90-ssl.cnf"
content: |
[server]
Expand All @@ -50,4 +50,4 @@
owner: "{{ mariadb_system_user.uid }}"
group: "{{ mariadb_system_user.gid }}"
notify: restart mariadb
tags: mariadb
tags: mariadb-ssl-config
30 changes: 16 additions & 14 deletions tasks/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,73 +2,75 @@
---

- name: Install server config file
template:
ansible.builtin.template:
src: etc_my.cnf.d_server.cnf.j2
dest: "{{ mariadb_config_server }}"
mode: '0640'
owner: "{{ mariadb_system_user.uid }}"
group: "{{ mariadb_system_user.gid }}"
notify: restart mariadb
tags: mariadb
tags: mariadb-config-server

- name: Install network config file
template:
ansible.builtin.template:
src: etc_my.cnf.d_network.cnf.j2
dest: "{{ mariadb_config_network }}"
mode: '0640'
owner: "{{ mariadb_system_user.uid }}"
group: "{{ mariadb_system_user.gid }}"
notify: restart mariadb
tags: mariadb
tags: mariadb-config-network

- name: Install custom config file
template:
ansible.builtin.template:
src: etc_my.cnf.d_custom.cnf.j2
dest: "{{ mariadb_config_custom }}"
mode: '0640'
owner: "{{ mariadb_system_user.uid }}"
group: "{{ mariadb_system_user.gid }}"
when: mariadb_custom_cnf|length != 0
notify: restart mariadb
tags: mariadb
tags: mariadb-config-custom

- name: Check if sysctl executable exists. If not, swappiness cannot be set!
stat:
ansible.builtin.stat:
path: /usr/sbin/sysctl
register: sysctl_check
tags: mariadb-config-swappiness

- name: Configure swappiness
sysctl:
ansible.posix.sysctl:
name: vm.swappiness
value: "{{ mariadb_swappiness }}"
state: present
when:
- mariadb_configure_swappiness|bool
- sysctl_check.stat.exists
tags: mariadb
tags: mariadb-config-swappiness

# SELinux context mysqld_log_t is default for /var/log/mariadb
- name: Create log directory
file:
ansible.builtin.file:
state: directory
path: /var/log/mariadb
owner: mysql
group: mysql
mode: '0755'
when: mariadb_logrotate.configure|bool
tags: mariadb-config-logs

- name: Configure logrotate
template:
ansible.builtin.template:
src: etc_logrotate.d_mysql.j2
dest: /etc/logrotate.d/mysql
mode: '0644'
when: mariadb_logrotate.configure|bool
notify: restart mariadb
tags: mariadb
tags: mariadb-config-logrotate

- name: Ensure service is started
service:
ansible.builtin.service:
name: "{{ mariadb_service }}"
state: started
enabled: true
tags: mariadb
tags: mariadb-config-service
Loading