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

feat: create playbook to install mysql8.4 #33

Merged
merged 7 commits into from
Jul 2, 2024
Merged
Show file tree
Hide file tree
Changes from 5 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
9 changes: 9 additions & 0 deletions mysql_8_4.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
# Playbook to provision MySQL

- name: Configure db MySQL instances
hosts: mysql_servers
become: True
gather_facts: True
roles:
- role: mysql_8_4
84 changes: 84 additions & 0 deletions roles/mysql_8_4/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
---
mysql_8_4_debian_pkgs:
- python3-mysqldb
- gpg

mysql_server_8_4_pkg: "mysql-server=8.4.*"
mysql_client_8_4_pkg: "mysql-client=8.4.*"
mysql_community_server_8_4_pkg: "mysql-server=8.4.*"

mysql_8_4_socket: /var/run/mysqld/mysqld.sock

MYSQL_8_4_APT_KEYSERVER: "keyserver.ubuntu.com"
MYSQL_8_4_APT_KEY: "A8D3785C"
MYSQL_8_4_REPO: "deb http://repo.mysql.com/apt//ubuntu/ {{ ansible_distribution_release }} mysql-8.4-lts"

MYSQL_8_4_SUPPORTED_DISTRIBUTIONS:
- "jammy"

# List of dictionaries as described in the mount_ebs role's default
# for the volumes.
# Useful if you want to store your MySQL data on separate
# disks from the root volume.
MYSQL_VOLUMES: []

# Mysql DB's in the form:
# MYSQL_CONFIG_DATABASES:
# - name: mydb
# collation: utf8_general_ci
# encoding: utf8
# state: present
MYSQL_CONFIG_DATABASES: []
# MYSQL_CONFIG_USERS:
# - name: myuser
# host: '%'
# password: 'strong_pass'
# priv: 'mydb.*:ALL'
# state: present
# append_privs: no
MYSQL_CONFIG_USERS: []

MYSQL_CONFIG_DEFAULT_ALLOWED_HOSTS: "%"

MYSQL_CONFIG_BIND_ADDRESS: "0.0.0.0"
MYSQL_CONFIG_PORT: 3306

MYSQL_CONFIG_SERVER_ID: 1

# In this path we store the MySQL configuration we create via templates
MYSQL_CONFIG_EXTRA_CONFIG_PATH: "/etc/mysql/mysql.conf.d"

# Using default MySQL 8.4 settings
# For more information check the links below:
# 8.4
# - https://dev.mysql.com/doc/refman/8.4/en/server-system-variables.html
# - https://dev.mysql.com/doc/refman/8.4/en/innodb-parameters.html

# Config for MySQL 8.4
# This variables are only compatible with MySQL 8.4
# More info: https://dev.mysql.com/doc/refman/8.4/en/added-deprecated-removed.html
MYSQL_CONFIG_EXPIRE_LOGS_SECONDS: 432000 # 5 days
MYSQL_CONFIG_INNODB_LOG_CAPACITY: 48M

MYSQL_CONFIG_CHARACTER_SET_SERVER: "utf8mb4"
MYSQL_CONFIG_COLLATION_SERVER: "utf8mb4_unicode_ci"
MYSQL_CONFIG_KEY_BUFFER_SIZE: 8M
MYSQL_CONFIG_MAX_CONNECTIONS: 1200
MYSQL_CONFIG_OPEN_FILES_LIMIT: 5000
MYSQL_CONFIG_TABLE_OPEN_CACHE: 2000
MYSQL_CONFIG_MAX_ALLOWED_PACKET: 16M
MYSQL_CONFIG_INNODB_BUFFER_POOL_SIZE: 128M
MYSQL_CONFIG_INNODB_IO_CAPACITY: 200
MYSQL_CONFIG_INNODB_IO_CAPACITY_MAX: 1000
MYSQL_CONFIG_INNODB_LOG_FILE_SIZE: 48M
MYSQL_CONFIG_INNODB_LOG_BUFFER_SIZE: 16M
MYSQL_CONFIG_INNODB_READ_IO_THREADS: 4
MYSQL_CONFIG_INNODB_WRITE_IO_THREADS: 4
MYSQL_CONFIG_INNODB_FLUSH_LOG_AT_TRX_COMMIT: 1

MYSQL_CONFIG_ENABLE_SLOW_QUERY_LOGS: false
MYSQL_CONFIG_READ_ONLY: false

# Replication
MYSQL_CONFIG_REPL_ENABLE_GTID_MODE: false
MYSQL_CONFIG_REPL_DISABLE_MYISAM: false
3 changes: 3 additions & 0 deletions roles/mysql_8_4/handlers/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
---
- name: restart mysql
service: name=mysql state=restarted
5 changes: 5 additions & 0 deletions roles/mysql_8_4/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
dependencies:
- common
- role: mount_ebs
volumes: "{{ MYSQL_VOLUMES }}"
26 changes: 26 additions & 0 deletions roles/mysql_8_4/tasks/configure.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
- name: Update mysql configuration
template:
src: mysqld.cnf.j2
dest: "{{ MYSQL_CONFIG_EXTRA_CONFIG_PATH }}/mysqld.cnf"
notify:
- restart mysql

- name: Put replication configuration file
template:
src: replication.cnf.j2
dest: "{{ MYSQL_CONFIG_EXTRA_CONFIG_PATH }}/replication.cnf"
notify:
- restart mysql

- name: Creating MySQL systemd custom dir
file:
path: /etc/systemd/system/mysql.service.d
state: directory

- name: Update mysql systemd configuration
template:
src: override.conf.j2
dest: /etc/systemd/system/mysql.service.d/override.conf
notify:
- restart mysql
10 changes: 10 additions & 0 deletions roles/mysql_8_4/tasks/databases.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
- name: Ensure MySQL databases are present.
mysql_db:
name: "{{ item.name }}"
collation: "{{ item.collation | default('') }}"
encoding: "{{ item.encoding | default('') }}"
state: "{{ item.state | default('present') }}"
target: "{{ item.target | default(omit) }}"
when: item.name != None and item.name != ''
with_items: "{{ MYSQL_CONFIG_DATABASES }}"
70 changes: 70 additions & 0 deletions roles/mysql_8_4/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
- name: Fail if trying to install on an unsupported distribution
fail:
msg: MySQL must be installed in a supported distribution
when: ansible_distribution_release not in MYSQL_8_4_SUPPORTED_DISTRIBUTIONS

- name: Install mysql dependencies
apt:
name: "{{ mysql_8_4_debian_pkgs }}"
install_recommends: yes
update_cache: yes
state: present

- name: Add MySQL repository key
apt_key:
keyserver: "{{ MYSQL_8_4_APT_KEYSERVER }}"
id: "{{ MYSQL_8_4_APT_KEY }}"
state: present

- name: Update APT cache
apt:
update_cache: yes

- name: Add MySQL repository to sources list
apt_repository:
repo: "{{ MYSQL_8_4_REPO }}"
state: present

# Installing mysql-8.4-client, mysql-8.4-community-server
# and mysql-8.4-server in separate tasks to resolve dependencies
- name: install mysql-8.4-client
apt:
name: "{{ mysql_client_8_4_pkg }}"
state: present
update_cache: yes

- name: install mysql-8.4-community-server
apt:
name: "{{ mysql_community_server_8_4_pkg }}"
state: present
update_cache: yes

- name: install mysql-8.4-server
apt:
name: "{{ mysql_server_8_4_pkg }}"
state: present
update_cache: yes

- name: restart mysql
command: service mysql restart

- name: Ensure Anonymous user(s) does not exist
mysql_user:
name: ''
host: "{{ item }}"
state: absent
login_unix_socket: "{{ mysql_8_4_socket }}"
with_items:
- localhost
- "{{ ansible_hostname }}"

- name: Alter user root to use caching_sha2_password
shell:
mysql -e "ALTER USER 'root'@'localhost' IDENTIFIED WITH caching_sha2_password; SET PASSWORD='';"
become: true

- name: Post MySQL installation configuration
include_tasks: configure.yml
- include_tasks: databases.yml
- include_tasks: users.yml
23 changes: 23 additions & 0 deletions roles/mysql_8_4/tasks/users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
---
marbonilla marked this conversation as resolved.
Show resolved Hide resolved
# Users are created manually because the mysql-users module in Ansible is still unable to
# create users correctly using the caching_sha2_password authentication plugin.
# As of now (20/06/2024), there is no release with the module fix.
# References
# https://github.com/ansible-collections/community.mysql/issues/621
# https://github.com/ansible-collections/community.mysql/pull/631
- name: Create and replace extra users
shell: |
mysql -e "CREATE USER IF NOT EXISTS '{{ item.name }}'@'{{ item.host }}' IDENTIFIED BY '{{ item.password }}';"
when: item.name != None and item.name != ''
loop: "{{ MYSQL_CONFIG_USERS }}"

- name: Adding users extra config
mysql_user:
name: "{{ item.name }}"
host: "{{ item.host | default(MYSQL_CONFIG_DEFAULT_ALLOWED_HOSTS) }}"
priv: "{{ item.priv if item.priv is defined else (item.db + '.*:ALL' if item.db is defined else '') }}"
state: "{{ item.state | default('present') }}"
append_privs: "{{ item.append_privs | default('no') }}"
encrypted: "{{ item.encrypted | default('no') }}"
when: item.name != None and item.name != ''
with_items: "{{ MYSQL_CONFIG_USERS }}"
117 changes: 117 additions & 0 deletions roles/mysql_8_4/templates/mysqld.cnf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#
# The MySQL database server configuration file.
#
# You can copy this to one of:
# - "/etc/mysql/my.cnf" to set global options,
# - "~/.my.cnf" to set user-specific options.
#
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
# https://dev.mysql.com/doc/refman/8.4/en/server-system-variables.html

# This will be passed to all mysql clients
# It has been reported that passwords should be enclosed with ticks/quotes
# escpecially if they contain "#" chars...
# Remember to edit /etc/mysql/debian.cnf when changing the socket location.

# Here is entries for some specific programs
# The following values assume you have at least 32M ram

[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0

[mysqld]
#
# * Basic Settings
#
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
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = {{ MYSQL_CONFIG_BIND_ADDRESS }}
#
# * Fine Tuning
#
key_buffer_size = {{ MYSQL_CONFIG_KEY_BUFFER_SIZE }}
max_allowed_packet = {{ MYSQL_CONFIG_MAX_ALLOWED_PACKET }}
thread_stack = 192K
thread_cache_size = 8
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover-options = BACKUP
max_connections = {{ MYSQL_CONFIG_MAX_CONNECTIONS }}
table_open_cache = {{ MYSQL_CONFIG_TABLE_OPEN_CACHE }}
open_files_limit = {{ MYSQL_CONFIG_OPEN_FILES_LIMIT }}
#table_cache = 64
#thread_concurrency = 10
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
#general_log_file = /var/log/mysql/mysql.log
#general_log = 1
#
# Error log - should be very few entries.
#
log_error = /var/log/mysql/error.log
#
{% if MYSQL_CONFIG_ENABLE_SLOW_QUERY_LOGS %}
# Here you can see queries with especially long duration
slow_query_log = 1
slow_query_log_file = /var/lib/mysql/slow-queries.log
long_query_time = 2
{% endif %}
#log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
# other settings you may need to change.
binlog_expire_logs_seconds = {{ MYSQL_CONFIG_EXPIRE_LOGS_SECONDS }}
read_only = {{ MYSQL_CONFIG_READ_ONLY }}
#binlog_do_db = include_database_name
#binlog_ignore_db = include_database_name
#
# * Character set and collation configuration
#
character-set-server = {{ MYSQL_CONFIG_CHARACTER_SET_SERVER }}
collation-server = {{ MYSQL_CONFIG_COLLATION_SERVER }}
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
#
# * Security Features
#
# Read the manual, too, if you want chroot!
# chroot = /var/lib/mysql/
#
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
#
# ssl-ca=/etc/mysql/cacert.pem
# ssl-cert=/etc/mysql/server-cert.pem
# ssl-key=/etc/mysql/server-key.pem

innodb_buffer_pool_size = {{ MYSQL_CONFIG_INNODB_BUFFER_POOL_SIZE }}
innodb_io_capacity = {{ MYSQL_CONFIG_INNODB_IO_CAPACITY }}
innodb_io_capacity_max = {{ MYSQL_CONFIG_INNODB_IO_CAPACITY_MAX }}
innodb_redo_log_capacity = {{ MYSQL_CONFIG_INNODB_LOG_CAPACITY }}
innodb_log_buffer_size = {{ MYSQL_CONFIG_INNODB_LOG_BUFFER_SIZE }}
innodb_read_io_threads = {{ MYSQL_CONFIG_INNODB_READ_IO_THREADS }}
innodb_write_io_threads = {{ MYSQL_CONFIG_INNODB_WRITE_IO_THREADS }}
innodb_flush_log_at_trx_commit = {{ MYSQL_CONFIG_INNODB_FLUSH_LOG_AT_TRX_COMMIT }}
2 changes: 2 additions & 0 deletions roles/mysql_8_4/templates/override.conf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[Service]
LimitNOFILE={{ MYSQL_CONFIG_OPEN_FILES_LIMIT }}
36 changes: 36 additions & 0 deletions roles/mysql_8_4/templates/replication.cnf.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
[mysqld]
server-id = {{ MYSQL_CONFIG_SERVER_ID }}

# Replication and binlog related options
# See: https://mysqlhighavailability.com/mysql-group-replication-a-quick-start-guide/
binlog-row-image = MINIMAL
binlog-rows-query-log-events = ON
log-bin-trust-function-creators = TRUE
max-binlog-size = 1G
relay-log-recovery = ON
slave-parallel-type = LOGICAL_CLOCK
slave-preserve-commit-order = ON
slave-parallel-workers = 8
slave-type-conversions = ALL_NON_LOSSY
sync-master-info = 1000
sync-relay-log = 1000


# Group replication pre-requisites & recommendations.
# See: https://mysqlhighavailability.com/mysql-group-replication-a-quick-start-guide/
log-bin
binlog-format = ROW
{% if MYSQL_CONFIG_REPL_ENABLE_GTID_MODE %}
gtid-mode = ON
{% endif %}
enforce-gtid-consistency = ON
log_slave_updates = ON
binlog-checksum = NONE
# prevent use of non-transactional storage engines
{% if MYSQL_CONFIG_REPL_DISABLE_MYISAM %}
disabled_storage_engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE"
{% endif %}
# InnoDB gap locks are problematic for multi-primary conflict detection; none are used with READ-COMMITTED
# So if you don't rely on REPEATABLE-READ semantics and/or wish to use multi-primary mode then this
# isolation level is recommended
transaction-isolation = 'READ-COMMITTED'
Loading