Skip to content

Commit

Permalink
Mysql DB role
Browse files Browse the repository at this point in the history
  • Loading branch information
sky-kshatriyan committed Jun 10, 2018
1 parent 489248d commit 123418a
Show file tree
Hide file tree
Showing 22 changed files with 632 additions and 80 deletions.
50 changes: 50 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
---
services: docker

env:
- distro: centos7
playbook: centos-7-test.yml
- distro: ubuntu1604
playbook: test.yml

script:
# Configure test script so we can run extra tests after playbook is run.
- export container_id=$(date +%s)
- export cleanup=false

# Download test shim.
- wget -O ${PWD}/tests/sdrtest.sh https://gist.githubusercontent.com/sky-kshatriyan/37d564e20e98d84b627b26b452b92c65/raw
- chmod +x ${PWD}/tests/sdrtest.sh

# Run tests.
- ${PWD}/tests/sdrtest.sh


# Some MySQL debugging (show all the logs).
- docker exec --tty ${container_id} env TERM=xterm ls -lah /var/log
- docker exec --tty ${container_id} env TERM=xterm cat /var/log/mysql/error.log || true
- docker exec --tty ${container_id} env TERM=xterm cat /var/log/mysql.err || true

# Check to make sure we can connect to MySQL via Unix socket.
- >
sudo docker exec ${container_id} mysql -u root -proot -e 'show databases;'
| grep -q 'information_schema'
&& (echo 'MySQL running normally' && exit 0)
|| (echo 'MySQL not running' && exit 1)
# Check to make sure we can connect to MySQL via TCP.
- >
sudo docker exec ${container_id} mysql -u root -proot -h 127.0.0.1 -e 'show databases;'
| grep -q 'information_schema'
&& (echo 'MySQL running normally' && exit 0)
|| (echo 'MySQL not running' && exit 1)
after_failure:
# Check MySQL settings.
- 'docker exec --tty ${container_id} env TERM=xterm cat /var/log/mysql/error.log'
- 'docker exec --tty ${container_id} env TERM=xterm cat /var/log/mysql.err'
- 'docker exec --tty ${container_id} env TERM=xterm cat /var/log/mysql.log'


notifications:
webhooks: https://galaxy.ansible.com/api/v1/notifications/
3 changes: 0 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,6 @@ All the variable that can be overridden are stored in [vars/main.yml](vars/main.
| `mysql_max_binlog_size` | 100M | Bin Log size |
| `mysql_binlog_format` | ROW | Log Format |
| `mysql_expire_logs_days` | 10 | Log expire days |
| `mysql_replication_role` | '' | Replication role |
| `mysql_replication_master` | '' | mysql replication master |
| `mysql_replication_user` | [] | mysql replication user name |

## Dependencies

Expand Down
3 changes: 2 additions & 1 deletion handlers/main.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
---
# handlers file for mysql
- name: restart mysql
service: "name={{ mysql_daemon }} state=restarted sleep=5"
75 changes: 75 additions & 0 deletions tasks/configure.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
- name: Copy my.cnf global MySQL configuration.
template:
src: my.cnf.j2
dest: "{{ mysql_config_file }}"
owner: root
group: root
mode: 0644
force: "{{ overwrite_global_mycnf }}"
notify: restart mysql

- name: Verify mysql include directory exists.
file:
path: "{{ mysql_config_include_dir }}"
state: directory
owner: root
group: root
mode: 0755
when: mysql_config_include_files | length

- name: Copy my.cnf override files into include directory.
template:
src: "{{ item.src }}"
dest: "{{ mysql_config_include_dir }}/{{ item.src | basename }}"
owner: root
group: root
mode: 0644
force: "{{ item.force | default(False) }}"
with_items: "{{ mysql_config_include_files }}"
notify: restart mysql

- name: Create slow query log file (if configured).
command: "touch {{ mysql_slow_query_log_file }}"
args:
creates: "{{ mysql_slow_query_log_file }}"
warn: no
when: mysql_slow_query_log_enabled

- name: Create datadir if it does not exist
file:
path: "{{ mysql_datadir }}"
state: directory
owner: mysql
group: mysql
mode: 0755
setype: mysqld_db_t

- name: Set ownership on slow query log file (if configured).
file:
path: "{{ mysql_slow_query_log_file }}"
state: file
owner: mysql
group: "{{ mysql_log_file_group }}"
mode: 0640
when: mysql_slow_query_log_enabled

- name: Create error log file (if configured).
command: "touch {{ mysql_log_error }}"
args:
creates: "{{ mysql_log_error }}"
warn: no
when: mysql_log == "" and mysql_log_error != ""

- name: Set ownership on error log file (if configured).
file:
path: "{{ mysql_log_error }}"
state: file
owner: mysql
group: "{{ mysql_log_file_group }}"
mode: 0640
when: mysql_log == "" and mysql_log_error != ""

- name: Ensure MySQL is started and enabled on boot.
service: "name={{ mysql_daemon }} state=started enabled={{ mysql_enabled_on_startup }}"
register: mysql_service_configuration
8 changes: 8 additions & 0 deletions tasks/databases.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Ensure MySQL databases are present.
mysql_db:
name: "{{ item.name }}"
collation: "{{ item.collation | default('utf8_general_ci') }}"
encoding: "{{ item.encoding | default('utf8') }}"
state: "{{ item.state | default('present') }}"
with_items: "{{ mysql_databases }}"
21 changes: 20 additions & 1 deletion tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,21 @@
---
# tasks file for mysql
# Variable configuration.
- include_tasks: variables.yml

# Setup/install tasks.
- include_tasks: setup-RedHat.yml
when: ansible_os_family == 'RedHat'

- include_tasks: setup-Debian.yml
when: ansible_os_family == 'Debian'

- name: Check if MySQL packages were installed.
set_fact:
mysql_install_packages: "{{ (rh_mysql_install_packages is defined and rh_mysql_install_packages.changed)
or (deb_mysql_install_packages is defined and deb_mysql_install_packages.changed) }}"

# Configure MySQL.
- include_tasks: configure.yml
- include_tasks: secure-installation.yml
- include_tasks: databases.yml
- include_tasks: users.yml
80 changes: 80 additions & 0 deletions tasks/secure-installation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
- name: Get MySQL version.
command: 'mysql --version'
register: mysql_cli_version
changed_when: false

- name: Ensure default user is present.
mysql_user:
name: "{{ mysql_user_name }}"
host: 'localhost'
password: "{{ mysql_user_password }}"
priv: '*.*:ALL,GRANT'
state: present
when: mysql_user_name != mysql_root_username

# Has to be after the password assignment, for idempotency.
- name: Copy user-my.cnf file with password credentials.
template:
src: "user-my.cnf.j2"
dest: "{{ mysql_user_home }}/.my.cnf"
owner: "{{ mysql_user_name }}"
mode: 0600
when: mysql_user_name != mysql_root_username and (mysql_install_packages | bool or mysql_user_password_update)

- name: Disallow root login remotely
command: 'mysql -NBe "{{ item }}"'
with_items:
- DELETE FROM mysql.user WHERE User='{{ mysql_root_username }}' AND Host NOT IN ('localhost', '127.0.0.1', '::1')
changed_when: false

- name: Get list of hosts for the root user.
command: mysql -NBe "SELECT Host FROM mysql.user WHERE User = '{{ mysql_root_username }}' ORDER BY (Host='localhost') ASC"
register: mysql_root_hosts
changed_when: false
check_mode: no
when: mysql_install_packages | bool or mysql_root_password_update

# Note: We do not use mysql_user for this operation, as it doesn't always update
# the root password correctly. See: https://goo.gl/MSOejW
# Set root password for MySQL >= 5.7.x.
- name: Update MySQL root password for localhost root account (5.7.x).
shell: >
mysql -u root -NBe
'ALTER USER "{{ mysql_root_username }}"@"{{ item }}" IDENTIFIED WITH mysql_native_password BY "{{ mysql_root_password }}";'
with_items: "{{ mysql_root_hosts.stdout_lines|default([]) }}"
when: ((mysql_install_packages | bool) or mysql_root_password_update) and ('5.7.' in mysql_cli_version.stdout)

# Set root password for MySQL < 5.7.x.
- name: Update MySQL root password for localhost root account (< 5.7.x).
shell: >
mysql -NBe
'SET PASSWORD FOR "{{ mysql_root_username }}"@"{{ item }}" = PASSWORD("{{ mysql_root_password }}");'
with_items: "{{ mysql_root_hosts.stdout_lines|default([]) }}"
when: ((mysql_install_packages | bool) or mysql_root_password_update) and ('5.7.' not in mysql_cli_version.stdout)

# Has to be after the root password assignment, for idempotency.
- name: Copy .my.cnf file with root password credentials.
template:
src: "root-my.cnf.j2"
dest: "{{ mysql_root_home }}/.my.cnf"
owner: root
group: root
mode: 0600
when: mysql_install_packages | bool or mysql_root_password_update

- name: Get list of hosts for the anonymous user.
command: mysql -NBe 'SELECT Host FROM mysql.user WHERE User = ""'
register: mysql_anonymous_hosts
changed_when: false
check_mode: no

- name: Remove anonymous MySQL users.
mysql_user:
name: ""
host: "{{ item }}"
state: absent
with_items: "{{ mysql_anonymous_hosts.stdout_lines|default([]) }}"

- name: Remove MySQL test database.
mysql_db: "name='test' state=absent"
33 changes: 33 additions & 0 deletions tasks/setup-Debian.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
- name: Check if MySQL is already installed.
stat: path=/etc/init.d/mysql
register: mysql_installed

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

- 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 }} state=present"

- name: Ensure MySQL packages are installed.
apt: "name={{ item }} state=present"
with_items: "{{ mysql_packages }}"
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"
when: mysql_installed.stat.exists == false

- name: Delete innodb log files created by apt package after initial install.
file: path={{ mysql_datadir }}/{{item}} state=absent
with_items:
- "ib_logfile0"
- "ib_logfile1"
when: mysql_installed.stat.exists == false
8 changes: 8 additions & 0 deletions tasks/setup-RedHat.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
- name: Ensure MySQL packages are installed.
yum: "name={{ item }} state=present enablerepo={{ mysql_enablerepo }}"
with_items: "{{ mysql_packages }}"
register: rh_mysql_install_packages

- name: Ensure MySQL Python libraries are installed.
yum: "name=MySQL-python state=present enablerepo={{ mysql_enablerepo }}"
12 changes: 12 additions & 0 deletions tasks/users.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
- name: Ensure MySQL users are present.
mysql_user:
name: "{{ item.name }}"
host: "{{ item.host | default('localhost') }}"
password: "{{ item.password }}"
priv: "{{ item.priv | default('*.*:USAGE') }}"
state: "{{ item.state | default('present') }}"
append_privs: "{{ item.append_privs | default('no') }}"
encrypted: "{{ item.encrypted | default('no') }}"
with_items: "{{ mysql_users }}"
no_log: true
63 changes: 63 additions & 0 deletions tasks/variables.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
# Variable configuration.
- name: Include OS-specific variables.
include_vars: "{{ item }}"
with_first_found:
- files:
- "vars/{{ ansible_os_family }}.yml"
skip: true
when: ansible_os_family != "RedHat"

- name: Include OS-specific variables (RedHat).
include_vars: "{{ ansible_os_family }}-{{ ansible_distribution_major_version }}.yml"
when: ansible_os_family == "RedHat"

- name: Define mysql_packages.
set_fact:
mysql_packages: "{{ __mysql_packages | list }}"
when: mysql_packages is not defined

- name: Define mysql_daemon.
set_fact:
mysql_daemon: "{{ __mysql_daemon }}"
when: mysql_daemon is not defined

- name: Define mysql_slow_query_log_file.
set_fact:
mysql_slow_query_log_file: "{{ __mysql_slow_query_log_file }}"
when: mysql_slow_query_log_file is not defined

- name: Define mysql_log_error.
set_fact:
mysql_log_error: "{{ __mysql_log_error }}"
when: mysql_log_error is not defined

- name: Define mysql_syslog_tag.
set_fact:
mysql_syslog_tag: "{{ __mysql_syslog_tag }}"
when: mysql_syslog_tag is not defined

- name: Define mysql_pid_file.
set_fact:
mysql_pid_file: "{{ __mysql_pid_file }}"
when: mysql_pid_file is not defined

- name: Define mysql_config_file.
set_fact:
mysql_config_file: "{{ __mysql_config_file }}"
when: mysql_config_file is not defined

- name: Define mysql_config_include_dir.
set_fact:
mysql_config_include_dir: "{{ __mysql_config_include_dir }}"
when: mysql_config_include_dir is not defined

- name: Define mysql_socket.
set_fact:
mysql_socket: "{{ __mysql_socket }}"
when: mysql_socket is not defined

- name: Define mysql_supports_innodb_large_prefix.
set_fact:
mysql_supports_innodb_large_prefix: "{{ __mysql_supports_innodb_large_prefix }}"
when: mysql_supports_innodb_large_prefix is not defined
Loading

0 comments on commit 123418a

Please sign in to comment.