Skip to content
Draft

test #589

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3a6c728
Use MySQL APT repository
damianlewis Sep 21, 2019
35f2958
Added instruction for changing the MySQL version
damianlewis Sep 21, 2019
76fa6cf
Updated meta to reflect forked role
damianlewis Sep 21, 2019
1486b40
Merge branch 'feature/mysql_versions' into develop
damianlewis Sep 21, 2019
5a9c9b5
Updated readme
damianlewis Mar 1, 2020
86af4ac
Updated readme
damianlewis Mar 18, 2020
24325ad
Add option to disable binary logging
augustobott Nov 13, 2020
b92eafc
Merge pull request #1 from exoticcaengineering/add_skip_binlog_option
augustobott Nov 13, 2020
5efb4c9
Update README.md
augustobott Nov 13, 2020
17c4ad7
Merge pull request #2 from exoticcaengineering/add_skip_binlog_option
augustobott Nov 13, 2020
85be29f
Update README, fix typos, add defaults
augustobott Nov 13, 2020
20c797a
Merge pull request #3 from exoticcaengineering/add_skip_binlog_option
augustobott Nov 13, 2020
40938e6
IT-8987 Add more innodb parameters to tweak performance.
tarantegui Sep 14, 2021
96fb003
IT-8987 Make additional configs optional
tarantegui Sep 15, 2021
8ca7153
Merge pull request #4 from exoticcaengineering/IT-8987-add-innodb-opt…
tarantegui Sep 15, 2021
c92577c
Incorporate changes in install from geerlingguy.mysqla role
tarantegui Jan 19, 2022
121d5bb
Merge pull request #6 from exoticcaengineering/IT-10998-hotfix-mysql-…
tarantegui Jan 19, 2022
8bba296
Upgrade GPG key for repo.mysql.com
tarantegui Jan 20, 2022
aee9d46
Merge branch 'master' into test
tarantegui Jan 20, 2022
c10f685
Update setup-Debian.yml
tarantegui Jan 20, 2022
bbcd0b8
Merge pull request #7 from exoticcaengineering/test
tarantegui Jan 20, 2022
998b0c6
Add switch to turn off innodb strict mode
tarantegui May 2, 2022
b3e5023
Merge pull request #8 from exoticcaengineering/hotfix-provision-database
tarantegui May 2, 2022
8dcbd8a
update mysql repo
jmlopezj Dec 20, 2023
e922aeb
Merge pull request #9 from exoticcaengineering/hotfix-mysql-repo
jmlopezj Jan 8, 2024
bfa394f
Remove deprecated command warn
carlos-mg89 Aug 16, 2024
69ce7cf
Merge pull request #10 from exoticcaengineering/remove-deprecated-com…
carlos-mg89 Aug 20, 2024
cd1e289
Fix delegate_to to comply with Ansible 2.16
carlos-mg89 Apr 24, 2025
d11f598
fix apt key and support to work with ansible 2.19
andrejex Jan 22, 2026
5e83a17
adding EOF
andrejex Jan 22, 2026
4ea9df3
Merge pull request #12 from exoticcaengineering/fix-apt-key
andrejex Jan 22, 2026
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
193 changes: 22 additions & 171 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,195 +1,46 @@
# Ansible Role: MySQL
This is a fork of the [damianlewis.mysql](https://github.com/damianlewis/ansible-role-mysql/) role which adds the ability to do things such as specify the MySQL version to install on Debian/Ubuntu platforms and disable binary logs.

[![Build Status](https://travis-ci.org/geerlingguy/ansible-role-mysql.svg?branch=master)](https://travis-ci.org/geerlingguy/ansible-role-mysql)

Installs and configures MySQL or MariaDB server on RHEL/CentOS or Debian/Ubuntu servers.
See [damianlewis.mysql](https://github.com/damianlewis/ansible-role-mysql/) and [geerlingguy.mysql](https://github.com/geerlingguy/ansible-role-mysql#ansible-role-mysql) for instructions on how to use this role.

## Requirements

No special requirements; note that this role requires root access, so either run it in a playbook with a global `become: yes`, or invoke the role in your playbook like:

- hosts: database
roles:
- role: geerlingguy.mysql
become: yes
None.

## Role Variables

Available variables are listed below, along with default values (see `defaults/main.yml`):

mysql_user_home: /root
mysql_user_name: root
mysql_user_password: root

The home directory inside which Python MySQL settings will be stored, which Ansible will use when connecting to MySQL. This should be the home directory of the user which runs this Ansible role. The `mysql_user_name` and `mysql_user_password` can be set if you are running this role under a non-root user account and want to set a non-root user.

mysql_root_home: /root
mysql_root_username: root
mysql_root_password: root

The MySQL root user account details.

mysql_root_password_update: false

Whether to force update the MySQL root user's password. By default, this role will only change the root user's password when MySQL is first configured. You can force an update by setting this to `yes`.

> Note: If you get an error like `ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)` after a failed or interrupted playbook run, this usually means the root password wasn't originally updated to begin with. Try either removing the `.my.cnf` file inside the configured `mysql_user_home` or updating it and setting `password=''` (the insecure default password). Run the playbook again, with `mysql_root_password_update` set to `yes`, and the setup should complete.

> Note: If you get an error like `ERROR 1698 (28000): Access denied for user 'root'@'localhost' (using password: YES)` when trying to log in from the CLI you might need to run as root or sudoer.

mysql_enabled_on_startup: true

Whether MySQL should be enabled on startup.

mysql_config_file: *default value depends on OS*
mysql_config_include_dir: *default value depends on OS*

The main my.cnf configuration file and include directory.

overwrite_global_mycnf: true

Whether the global my.cnf should be overwritten each time this role is run. Setting this to `no` tells Ansible to only create the `my.cnf` file if it doesn't exist. This should be left at its default value (`yes`) if you'd like to use this role's variables to configure MySQL.

mysql_config_include_files: []

A list of files that should override the default global my.cnf. Each item in the array requires a "src" parameter which is a path to a file. An optional "force" parameter can force the file to be updated each time ansible runs.

mysql_databases: []

The MySQL databases to create. A database has the values `name`, `encoding` (defaults to `utf8`), `collation` (defaults to `utf8_general_ci`) and `replicate` (defaults to `1`, only used if replication is configured). The formats of these are the same as in the `mysql_db` module.

You can also delete a database (or ensure it's not on the server) by setting `state` to `absent` (defaults to `present`).

mysql_users: []

The MySQL users and their privileges. A user has the values:

- `name`
- `host` (defaults to `localhost`)
- `password` (can be plaintext or encrypted—if encrypted, set `encrypted: yes`)
- `encrypted` (defaults to `no`)
- `priv` (defaults to `*.*:USAGE`)
- `append_privs` (defaults to `no`)
- `state` (defaults to `present`)

The formats of these are the same as in the `mysql_user` module.

mysql_packages:
- mysql
- mysql-server

(OS-specific, RedHat/CentOS defaults listed here) Packages to be installed. In some situations, you may need to add additional packages, like `mysql-devel`.

mysql_enablerepo: ""

(RedHat/CentOS only) If you have enabled any additional repositories (might I suggest geerlingguy.repo-epel or geerlingguy.repo-remi), those repositories can be listed under this variable (e.g. `remi,epel`). This can be handy, as an example, if you want to install later versions of MySQL.

mysql_port: "3306"
mysql_bind_address: '0.0.0.0'
mysql_datadir: /var/lib/mysql
mysql_socket: *default value depends on OS*
mysql_pid_file: *default value depends on OS*

Default MySQL connection configuration.

mysql_log_file_group: mysql *adm on Debian*
mysql_log: ""
mysql_log_error: *default value depends on OS*
mysql_syslog_tag: *default value depends on OS*

MySQL logging configuration. Setting `mysql_log` (the general query log) or `mysql_log_error` to `syslog` will make MySQL log to syslog using the `mysql_syslog_tag`.

mysql_slow_query_log_enabled: false
mysql_slow_query_log_file: *default value depends on OS*
mysql_slow_query_time: 2

Slow query log settings. Note that the log file will be created by this role, but if you're running on a server with SELinux or AppArmor, you may need to add this path to the allowed paths for MySQL, or disable the mysql profile. For example, on Debian/Ubuntu, you can run `sudo ln -s /etc/apparmor.d/usr.sbin.mysqld /etc/apparmor.d/disable/usr.sbin.mysqld && sudo service apparmor restart`.

mysql_key_buffer_size: "256M"
mysql_max_allowed_packet: "64M"
mysql_table_open_cache: "256"
[...]

The rest of the settings in `defaults/main.yml` control MySQL's memory usage and some other common settings. The default values are tuned for a server where MySQL can consume ~512 MB RAM, so you should consider adjusting them to suit your particular server better.

mysql_server_id: "1"
mysql_max_binlog_size: "100M"
mysql_binlog_format: "ROW"
mysql_expire_logs_days: "10"
mysql_replication_role: ''
mysql_replication_master: ''
mysql_replication_user: {}

Replication settings. Set `mysql_server_id` and `mysql_replication_role` by server (e.g. the master would be ID `1`, with the `mysql_replication_role` of `master`, and the slave would be ID `2`, with the `mysql_replication_role` of `slave`). The `mysql_replication_user` uses the same keys as individual list items in `mysql_users`, and is created on master servers, and used to replicate on all the slaves.

`mysql_replication_master` needs to resolve to an IP or a hostname which is accessable to the Slaves (this could be a `/etc/hosts` injection or some other means), otherwise the slaves cannot communicate to the master.

### Later versions of MySQL on CentOS 7

If you want to install MySQL from the official repository instead of installing the system default MariaDB equivalents, you can add the following `pre_tasks` task in your playbook:
Available variables are listed below, along with their default values.
See [damianlewis.mysql](https://github.com/damianlewis/ansible-role-mysql/) and [geerlingguy.mysql role variables](https://github.com/geerlingguy/ansible-role-mysql#role-variables) for information on the core variables that this role uses.

```yaml
pre_tasks:
- name: Install the MySQL repo.
yum:
name: http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
state: present
when: ansible_os_family == "RedHat"

- name: Override variables for MySQL (RedHat).
set_fact:
mysql_daemon: mysqld
mysql_packages: ['mysql-server']
mysql_log_error: /var/log/mysqld.err
mysql_syslog_tag: mysqld
mysql_pid_file: /var/run/mysqld/mysqld.pid
mysql_socket: /var/lib/mysql/mysql.sock
when: ansible_os_family == "RedHat"
mysql_version: "5.7"
mysql_skip_log_bin: false
```

### MariaDB usage

This role works with either MySQL or a compatible version of MariaDB. On RHEL/CentOS 7+, the mariadb database engine was substituted as the default MySQL replacement package. No modifications are necessary though all of the variables still reference 'mysql' instead of mariadb.

#### Ubuntu 14.04 and 16.04 MariaDB configuration

On Ubuntu, the package names are named differently, so the `mysql_package` variable needs to be altered. Set the following variables (at a minimum):

mysql_packages:
- mariadb-client
- mariadb-server
- python-mysqldb
MySQL installation settings.
- `mysql_version:string` - Specifies which version of MySQL to install.

## Dependencies

None.

## Example Playbook
```yaml
- hosts: server
become: yes

- hosts: db-servers
become: yes
vars_files:
- vars/main.yml
roles:
- { role: geerlingguy.mysql }

*Inside `vars/main.yml`*:

vars:
mysql_version: "8.0"
mysql_skip_name_resolve: true
mysql_skip_log_bin: true
mysql_root_password: super-secure-password
mysql_databases:
- name: example_db
encoding: latin1
collation: latin1_general_ci
encoding: utf8
collation: utf8_general_ci
mysql_users:
- name: example_user
host: "%"
password: similarly-secure-password
priv: "example_db.*:ALL"

## License

MIT / BSD

## Author Information

This role was created in 2014 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/).
tasks:
- import_role:
name: exoticca.mysql
```
4 changes: 4 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ overwrite_global_mycnf: true
# for RedHat systems (and derivatives).
mysql_enablerepo: ""

# Version of MySQL to install. Used only for Debian/Ubuntu systems.
mysql_version: "5.7"

# Define a custom list of packages to install; if none provided, the default
# package list from vars/[OS-family].yml will be used.
# mysql_packages:
Expand All @@ -38,6 +41,7 @@ mysql_enablerepo: ""
mysql_port: "3306"
mysql_bind_address: '0.0.0.0'
mysql_skip_name_resolve: false
mysql_skip_log_bin: false
mysql_datadir: /var/lib/mysql
mysql_sql_mode: ''
# The following variables have a default value depending on operating system.
Expand Down
12 changes: 7 additions & 5 deletions meta/main.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
dependencies: []

galaxy_info:
author: geerlingguy
role_name: mysql
author: Damian Lewis
description: MySQL server for RHEL/CentOS and Debian/Ubuntu.
company: "Midwestern Mac, LLC"
license: "license (BSD, MIT)"
license: MIT

min_ansible_version: 2.4

platforms:
- name: EL
versions:
Expand All @@ -27,3 +27,5 @@ galaxy_info:
- mariadb
- db
- sql

dependencies: []
4 changes: 1 addition & 3 deletions tasks/configure.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
owner: root
group: root
mode: 0755
when: mysql_config_include_files | length
when: mysql_config_include_files | length | bool

- name: Copy my.cnf override files into include directory.
template:
Expand All @@ -39,7 +39,6 @@
command: "touch {{ mysql_slow_query_log_file }}"
args:
creates: "{{ mysql_slow_query_log_file }}"
warn: false
when: mysql_slow_query_log_enabled

- name: Create datadir if it does not exist
Expand All @@ -64,7 +63,6 @@
command: "touch {{ mysql_log_error }}"
args:
creates: "{{ mysql_log_error }}"
warn: false
when:
- mysql_log == ""
- mysql_log_error != ""
Expand Down
2 changes: 1 addition & 1 deletion tasks/replication.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

- name: Check master replication status.
mysql_replication: mode=getmaster
delegate_to: "{{ mysql_replication_master }}"
delegate_to: "{{ mysql_replication_master | default(omit, true) }}"
register: master
when:
- (slave.Is_Slave is defined and not slave.Is_Slave) or (slave.Is_Slave is not defined and slave is failed)
Expand Down
30 changes: 18 additions & 12 deletions tasks/setup-Debian.yml
Original file line number Diff line number Diff line change
@@ -1,36 +1,42 @@
---
- name: Check if MySQL is already installed.
stat: path=/etc/init.d/mysql
ansible.builtin.stat:
path: "{{ mysql_config_file }}"
register: mysql_installed

- name: Update apt cache if MySQL is not yet installed.
apt: update_cache=yes
ansible.builtin.apt:
update_cache: true
changed_when: false
when: not mysql_installed.stat.exists

- name: Determine required MySQL Python libraries.
set_fact:
deb_mysql_python_package: "{% if 'python3' in ansible_python_interpreter|default('') %}python3-mysqldb{% else %}python-mysqldb{% endif %}"

- name: Ensure MySQL Python libraries are installed.
apt:
name: "{{ deb_mysql_python_package }}"
ansible.builtin.apt:
name: "python3-mysqldb"
state: present

- name: Ensure MySQL packages are installed.
apt:
ansible.builtin.apt:
name: "{{ mysql_packages }}"
state: present
policy_rc_d: 101
register: deb_mysql_install_packages

# Because Ubuntu starts MySQL as part of the install process, we need to stop
# mysql and remove the logfiles in case the user set a custom log file size.
- name: Ensure MySQL is stopped after initial install.
service: "name={{ mysql_daemon }} state=stopped"
ansible.builtin.service:
name: "{{ mysql_daemon }}"
state: stopped
when: not mysql_installed.stat.exists

- name: Delete innodb log files created by apt package after initial install.
file: path={{ mysql_datadir }}/{{ item }} state=absent
ansible.builtin.file:
path: "{{ mysql_datadir }}/{{ item }}"
state: absent
with_items:
- ib_logfile0
- ib_logfile1
when: not mysql_installed.stat.exists
when: >
not mysql_installed.stat.exists
and ansible_facts.distribution_major_version | int < 12
6 changes: 6 additions & 0 deletions templates/my.cnf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ pid-file = {{ mysql_pid_file }}
{% if mysql_skip_name_resolve %}
skip-name-resolve
{% endif %}
{% if mysql_skip_log_bin %}
skip-log-bin
{% endif %}
{% if mysql_sql_mode %}
sql_mode = {{ mysql_sql_mode }}
{% endif %}
Expand Down Expand Up @@ -104,10 +107,13 @@ innodb_file_format = {{ mysql_innodb_file_format }}
{% endif %}
innodb_file_per_table = {{ mysql_innodb_file_per_table }}
innodb_buffer_pool_size = {{ mysql_innodb_buffer_pool_size }}
innodb_buffer_pool_instances = {{ mysql_innodb_buffer_pool_instances | default('1') }}
innodb_log_file_size = {{ mysql_innodb_log_file_size }}
innodb_log_buffer_size = {{ mysql_innodb_log_buffer_size }}
innodb_flush_log_at_trx_commit = {{ mysql_innodb_flush_log_at_trx_commit }}
innodb_lock_wait_timeout = {{ mysql_innodb_lock_wait_timeout }}
innodb_stats_on_metadata = {{ mysql_innodb_stats_on_metadata | default('ON') }}
innodb_strict_mode = {{ mysql_innodb_strict_mode | default('ON') }}

[mysqldump]
quick
Expand Down