diff --git a/.travis.yml b/.travis.yml index 68498ce..5ce16a0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,13 @@ env: - - PLATFORM='docker-stretch-default-mariadb-master' ANSIBLE_VERSION='ansible>=2.5,<2.6' - - PLATFORM='docker-stretch-upstream-mariadb-master' ANSIBLE_VERSION='ansible>=2.5,<2.6' - - PLATFORM='docker-stretch-upstream-mariadbgalera-1' ANSIBLE_VERSION='ansible>=2.5,<2.6' - - PLATFORM='docker-stretch-default-mariadb-master' ANSIBLE_VERSION='ansible>=2.6,<2.7' - - PLATFORM='docker-stretch-upstream-mariadb-master' ANSIBLE_VERSION='ansible>=2.6,<2.7' - - PLATFORM='docker-stretch-upstream-mariadbgalera-1' ANSIBLE_VERSION='ansible>=2.6,<2.7' - - PLATFORM='docker-stretch-default-mariadb-master' ANSIBLE_VERSION='ansible>=2.7,<2.7' - - PLATFORM='docker-stretch-upstream-mariadb-master' ANSIBLE_VERSION='ansible>=2.7,<2.7' - - PLATFORM='docker-stretch-upstream-mariadbgalera-1' ANSIBLE_VERSION='ansible>=2.7,<2.7' + - PLATFORM='docker-stretch-default-master' ANSIBLE_VERSION='ansible>=2.5,<2.6' + - PLATFORM='docker-stretch-upstream-master' ANSIBLE_VERSION='ansible>=2.5,<2.6' + - PLATFORM='docker-stretch-upstream-galera-1' ANSIBLE_VERSION='ansible>=2.5,<2.6' + - PLATFORM='docker-stretch-default-master' ANSIBLE_VERSION='ansible>=2.6,<2.7' + - PLATFORM='docker-stretch-upstream-master' ANSIBLE_VERSION='ansible>=2.6,<2.7' + - PLATFORM='docker-stretch-upstream-galera-1' ANSIBLE_VERSION='ansible>=2.6,<2.7' + - PLATFORM='docker-stretch-default-master' ANSIBLE_VERSION='ansible>=2.7,<2.8' + - PLATFORM='docker-stretch-upstream-master' ANSIBLE_VERSION='ansible>=2.7,<2.8' + - PLATFORM='docker-stretch-upstream-galera-1' ANSIBLE_VERSION='ansible>=2.7,<2.8' sudo: required diff --git a/README.md b/README.md index 8ebc879..11a9e5d 100644 --- a/README.md +++ b/README.md @@ -5,11 +5,10 @@ MariaDB (MySQL) Ansible role for Debian Install and configure MariaDB (Galera Cluster). Manage replication (master/slave). Create users and databases. -| OS | Vendor | Origin | Managed versions | -| --------------- | ----------------------- | --------- | ------------------------- | -| Debian Stretch | MariaDB | Debian | 10.1 | -| Debian Stretch | MariaDB | Upstream | 10.1 / 10.2 / 10.3 | -| Debian Stretch | MariaDB Galera Cluster | Upstream | 10.1 / 10.2 | +| OS | Origin | MariaDB versions | +| --------------- | --------- | ------------------------- | +| Debian Stretch | Debian | 10.1 | +| Debian Stretch | Upstream | 10.1 / 10.2 / 10.3 / 10.4 | Notes ----- @@ -26,8 +25,7 @@ Ansible 2.5+ Role Variables -------------- -- `mariadb_origin`: origin of the package ("default" or "upstream") -- `mariadb_vendor`: "mariadb", "mariadb\_galera" +- `mariadb_use_galera`: set true to configure and install Galera Cluster ### Configuration @@ -76,7 +74,7 @@ Example Playbook - hosts: servers roles: - - { role: HanXHX.mysql, mariadb_origin: 'upstream', mariadb_vendor: 'mariadb' } + - { role: HanXHX.mysql, mariadb_origin: 'upstream' } License ------- diff --git a/Vagrantfile b/Vagrantfile index bd5651e..626399f 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -16,13 +16,13 @@ Vagrant.configure("2") do |config| cases = [ # Debian Stretch - { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mariadb_origin: 'default', mariadb_vendor: 'mariadb' }, groups: ['master'] }, - { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mariadb_origin: 'default', mariadb_vendor: 'mariadb' }, groups: ['slave'] }, - { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mariadb_origin: 'upstream', mariadb_vendor: 'mariadb' }, groups: ['master'] }, - { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mariadb_origin: 'upstream', mariadb_vendor: 'mariadb' }, groups: ['slave'] }, - { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mariadb_origin: 'upstream' }, groups: ['mariadbgalera', '1'] }, - { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mariadb_origin: 'upstream' }, groups: ['mariadbgalera', '2'] }, - { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mariadb_origin: 'upstream' }, groups: ['mariadbgalera', '3'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mariadb_origin: 'default' }, groups: ['master'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mariadb_origin: 'default' }, groups: ['slave'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mariadb_origin: 'upstream' }, groups: ['master'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mariadb_origin: 'upstream' }, groups: ['slave'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: dk_deb_stretch, vars: {mariadb_origin: 'upstream' }, groups: ['galera', '1'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mariadb_origin: 'upstream' }, groups: ['galera', '2'] }, + { os_name: 'stretch', vbox: vbox_deb_stretch, docker: nil, vars: {mariadb_origin: 'upstream' }, groups: ['galera', '3'] }, ] cases.each_with_index do |opts,index| diff --git a/defaults/main.yml b/defaults/main.yml index 9f6035b..f3b6085 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -4,7 +4,7 @@ # Setup # ------------------------------------- mariadb_origin: 'default' -mariadb_vendor: 'mariadb' +mariadb_use_galera: false mariadb_root_password: 'change_me_NOW' mariadb_notify_restart: true mariadb_upstream_apt_src: false @@ -135,6 +135,7 @@ mariadb_key_ids: ['0xcbcb082a1bb943db', '0xf1656f24c74cd1d8'] # Galera # ------------------------------------- mariadb_galera_resetup: false +mariadb_wsrep_node_address: false # Set primary node IP mariadb_galera_members: [] mariadb_galera_primary_node: 'change_me' # See: https://github.com/ansible/ansible/issues/17453 mariadb_wsrep_stt_method: 'rsync' diff --git a/tasks/galera/bootstrap.yml b/tasks/galera/bootstrap.yml index 554a2aa..15cae97 100644 --- a/tasks/galera/bootstrap.yml +++ b/tasks/galera/bootstrap.yml @@ -1,9 +1,11 @@ --- -- set_fact: - booboo: "{{ mariadb_datadir }}/.ansible_galera_boostrap" +- name: SET_FACT | Prepare mark var + set_fact: + __mark: "{{ mariadb_datadir }}/.ansible_galera_boostrap" - name: STAT | Bootstrap mark - stat: path={{ booboo }} + stat: + path: "{{ __mark }}" register: s - block: @@ -12,7 +14,9 @@ mariadb_notify_restart: false - name: SERVICE | Stop MariaDB - service: name=mysql state=stopped + service: + name: mysql + state: stopped - name: COMMAND | Bootstrap first node (systemd) command: galera_new_cluster @@ -29,6 +33,6 @@ when: not s.stat.exists or mariadb_galera_resetup - name: COMMAND | Create Bootstrap mark - command: "touch {{ booboo }}" + command: "touch {{ __mark }}" args: - creates: "{{ booboo }}" + creates: "{{ __mark }}" diff --git a/tasks/galera/main.yml b/tasks/galera/main.yml index a83ca90..89efc79 100644 --- a/tasks/galera/main.yml +++ b/tasks/galera/main.yml @@ -7,18 +7,18 @@ register: galeraconfig - name: INCLUDE | Bootstrap first node - include: 'bootstrap.yml' + import_tasks: 'bootstrap.yml' when: inventory_hostname == mariadb_galera_primary_node - name: INCLUDE | Configure other nodes - include: 'nodes.yml' + import_tasks: 'nodes.yml' when: inventory_hostname != mariadb_galera_primary_node - name: SERVICE | Restart MariaDB if needed service: name: mysql state: restarted - when: > + when: ((galeraconfig or (p is defined and p.changed)) and (bootstrap_run is not defined)) or ((inventory_hostname != mariadb_galera_primary_node) and diff --git a/tasks/install/main.yml b/tasks/install/main.yml index 2500194..0e24628 100644 --- a/tasks/install/main.yml +++ b/tasks/install/main.yml @@ -1,17 +1,16 @@ --- -- name: INCLUDE | Use Percona repository - include: 'percona/apt.yml' +- name: INCLUDE | Setup Percona repository + import_tasks: 'percona/apt.yml' when: mariadb_use_percona_apt -- name: INCLUDE | Install MariaDB from Debian repo - include: 'mariadb/default.yml' - when: mariadb_origin == 'default' and mariadb_vendor == 'mariadb' - -- name: INCLUDE | Install MariaDB from MariaDB repo - include: 'mariadb/upstream.yml' +- name: INCLUDE | Setup MariaDB repository + import_tasks: 'mariadb/upstream.yml' when: mariadb_origin == 'upstream' +- name: INCLUDE | Install MariaDB + import_tasks: 'mariadb/default.yml' + - name: APT | Install few MariaDB related tools apt: pkg: "{{ mariadb_tools }}" diff --git a/tasks/install/mariadb/default.yml b/tasks/install/mariadb/default.yml index 699e26b..749cb49 100644 --- a/tasks/install/mariadb/default.yml +++ b/tasks/install/mariadb/default.yml @@ -28,4 +28,4 @@ - name: APT | Install Galera apt: pkg: galera-3 - when: mariadb_vendor == 'mariadb_galera' + when: mariadb_use_galera diff --git a/tasks/install/mariadb/upstream.yml b/tasks/install/mariadb/upstream.yml index dbd07ad..bb389af 100644 --- a/tasks/install/mariadb/upstream.yml +++ b/tasks/install/mariadb/upstream.yml @@ -19,6 +19,3 @@ apt_repository: repo: 'deb-src {{ mariadb_repository }} {{ ansible_distribution_release }} main' when: mariadb_upstream_apt_src - -- name: INCLUDE | Normal Install - include: default.yml diff --git a/tasks/main.yml b/tasks/main.yml index d7f1503..cf9d7e1 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -10,7 +10,7 @@ changed_when: false - name: INCLUDE | Install - include: install/main.yml + import_tasks: install/main.yml - name: TEMPLATE | Deploy configuration template: @@ -28,7 +28,7 @@ service: name: mysql state: restarted - when: > + when: (config.changed or extraconfig.changed) and not mariadb_galera_resetup @@ -42,15 +42,15 @@ backup: yes - name: INCLUDE | Galera - include: galera/main.yml - when: mariadb_vendor == 'mariadb_galera' + import_tasks: galera/main.yml + when: mariadb_use_galera - name: INCLUDE | Replication - include: replication/main.yml + import_tasks: replication/main.yml when: mariadb_replication_master or mariadb_replication_slave - name: INCLUDE | Secure install - include: 'secure.yml' + import_tasks: 'secure.yml' - name: SERVICE | Ensure service is started service: diff --git a/tasks/replication/main.yml b/tasks/replication/main.yml index 498c219..d719cfd 100644 --- a/tasks/replication/main.yml +++ b/tasks/replication/main.yml @@ -1,9 +1,9 @@ --- - name: INCLUDE | Replication Master - include: master.yml + import_tasks: master.yml when: mariadb_replication_master - name: INCLUDE | Replication slave - include: slave.yml + import_tasks: slave.yml when: mariadb_replication_slave diff --git a/tasks/replication/slave.yml b/tasks/replication/slave.yml index 389e7d5..3eb9bd9 100644 --- a/tasks/replication/slave.yml +++ b/tasks/replication/slave.yml @@ -19,19 +19,19 @@ register: slave_status - name: INCLUDE | Transfert /etc/mysql/debian.cnf from master - include: slave/ssh.yml + import_tasks: slave/ssh.yml when: mariadb_slave_replicate_mysqldb or ((slave_status.failed is defined or not slave_status.Is_Slave) and mariadb_slave_import_data) - name: INCLUDE | Import data - include: slave/import_data.yml + import_tasks: slave/import_data.yml when: (slave_status.failed is defined or not slave_status.Is_Slave) and mariadb_slave_import_data - name: INCLUDE | Configure replication - include: slave/replication.yml + import_tasks: slave/replication.yml when: (slave_status.failed is defined or not slave_status.Is_Slave) or mariadb_slave_force_setup - name: INCLUDE | Transfert /etc/mysql/debian.cnf from master - include: slave/debiancnf.yml + import_tasks: slave/debiancnf.yml when: mariadb_slave_replicate_mysqldb - name: MYSQL_REPLICATION | Get slave status @@ -41,4 +41,4 @@ register: slave_status - name: Configure GTID - include: slave/gtid.yml + import_tasks: slave/gtid.yml diff --git a/tasks/replication/slave/debiancnf.yml b/tasks/replication/slave/debiancnf.yml index 172c840..efc90ea 100644 --- a/tasks/replication/slave/debiancnf.yml +++ b/tasks/replication/slave/debiancnf.yml @@ -9,7 +9,10 @@ delegate_to: "{{ mariadb_slave_import_from }}" - name: LOCAL_ACTION FILE | Secure fetched file - local_action: file path=/tmp/{{ mariadb_slave_import_from }}/debian.cnf mode=0600 + local_action: + module: file + path: "/tmp/{{ mariadb_slave_import_from }}/debian.cnf" + mode: 0600 become: no - name: COPY | Fetched file to /etc/mysql/debian.cnf diff --git a/tasks/replication/slave/import_data.yml b/tasks/replication/slave/import_data.yml index 366504b..4f1204b 100644 --- a/tasks/replication/slave/import_data.yml +++ b/tasks/replication/slave/import_data.yml @@ -7,7 +7,9 @@ port: 22 - name: COMMAND | Prepare backup another server - command: innobackupex --no-timestamp {{ mariadb_backup_dir }} creates={{ mariadb_backup_dir }} + command: innobackupex --no-timestamp {{ mariadb_backup_dir }} + args: + creates: "{{ mariadb_backup_dir }}" delegate_to: "{{ mariadb_slave_import_from }}" register: backup @@ -24,7 +26,8 @@ when: backup.changed and not mariadb_slave_replicate_mysqldb - name: MYSQL_VARIABLES | Get datadir - mysql_variables: variable=datadir + mysql_variables: + variable: datadir register: datadir - name: SET_FACT | related to mysql datadir @@ -74,6 +77,8 @@ mariadb_master_gtid: "{{ master_gtid.stdout }}" - name: FILE | Delete dump - file: path={{ mariadb_backup_dir }} state=absent + file: + path: "{{ mariadb_backup_dir }}" + state: absent delegate_to: "{{ mariadb_slave_import_from }}" when: mariadb_slave_import_flush_dump diff --git a/templates/etc/mysql/conf.d/09-galera.cnf.j2 b/templates/etc/mysql/conf.d/09-galera.cnf.j2 index 3f51243..9d6b22e 100644 --- a/templates/etc/mysql/conf.d/09-galera.cnf.j2 +++ b/templates/etc/mysql/conf.d/09-galera.cnf.j2 @@ -18,7 +18,7 @@ wsrep_cluster_name="{{ mariadb_wsrep_cluster_name }}" {% endif %} # Node Configuration -wsrep_node_address="{{ mariadb_wsrep_node_address | default(ansible_default_ipv4.address) }}" +wsrep_node_address="{{ mariadb_wsrep_node_address | default(ansible_default_ipv4.address if ansible_default_ipv4 is defined else '127.0.0.1') }}" wsrep_node_name="{{ mariadb_wsrep_node_name | default(ansible_fqdn) }}" diff --git a/tests/group_vars/mariadbgalera b/tests/group_vars/galera similarity index 52% rename from tests/group_vars/mariadbgalera rename to tests/group_vars/galera index 7ab50d4..7dbf857 100644 --- a/tests/group_vars/mariadbgalera +++ b/tests/group_vars/galera @@ -1,5 +1,5 @@ -mariadb_vendor: 'mariadb_galera' +mariadb_use_galera: true mariadb_galera_members: - - '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-mariadbgalera-1' - - '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-mariadbgalera-2' - - '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-mariadbgalera-3' + - '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-galera-1' + - '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-galera-2' + - '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-galera-3' diff --git a/tests/group_vars/mysql b/tests/group_vars/mysql deleted file mode 100644 index ad6c9f1..0000000 --- a/tests/group_vars/mysql +++ /dev/null @@ -1 +0,0 @@ -mariadb_vendor: 'mysql' diff --git a/tests/test.yml b/tests/test.yml index 23c9def..65b7a84 100644 --- a/tests/test.yml +++ b/tests/test.yml @@ -1,21 +1,37 @@ --- - hosts: all + gather_facts: false + pre_tasks: + - name: SETUP | Get facts + setup: + register: s + - name: DEBUG | Show facts + debug: + var: s tasks: - - apt: pkg={{ item }} state=present update_cache=yes cache_valid_time=3600 - loop: - - ca-certificates - - curl - - strace - - vim + - name: APT | Install some packages + apt: + name: "{{ p }}" + update_cache: yes + cache_valid_time: 3600 + vars: + p: ['ca-certificates', 'curl', 'strace', 'vim'] - hosts: master roles: - ../../ tasks: - - copy: src=import1.sql dest=/tmp/import1.sql + - name: COPY | Deploy first dump + copy: + src: import1.sql + dest: /tmp/import1.sql register: c - - mysql_db: name={{ item }} state=import target=/tmp/import1.sql + - name: MYSQL_DB | Import first dump + mysql_db: + name: "{{ item }}" + state: import + target: /tmp/import1.sql loop: ['testrepl', 'norepl'] when: c.changed @@ -25,7 +41,8 @@ shell: getent hosts {{ ansible_hostname | replace ('slave', 'master') }} | cut -d ' ' -f 1 register: ip changed_when: false - - set_fact: + - name: SET_FACT | Apply some configuration + set_fact: # MariaDB don't read /etc/hosts (from vagrant host plugin) mariadb_replication_host: "{{ ip.stdout }}" # Need this to use vagrant 'delegate_to' @@ -33,27 +50,35 @@ roles: - ../../ tasks: - - copy: src=import2.sql dest=/tmp/import2.sql + - name: COPY | Deploy dump + copy: + src: import2.sql + dest: /tmp/import2.sql delegate_to: "{{ mariadb_slave_import_from }}" register: c - - mysql_db: name={{ item }} state=import target=/tmp/import2.sql + - name: MYSQL_DB | Import another dump + mysql_db: + name: "{{ item }}" + state: import + target: /tmp/import2.sql loop: ['testrepl', 'norepl'] delegate_to: "{{ mariadb_slave_import_from }}" when: c.changed - - mysql_replication: mode=getslave + - name: MYSQL_REPLICATION | Get slave infos + mysql_replication: + mode: getslave register: slave - - fail: msg="Slave issue" + - name: FAIL | if slave threads are not running + fail: + msg: "Slave issue" when: slave.Slave_IO_Running != 'Yes' or slave.Slave_SQL_Running != 'Yes' -- hosts: mariadbgalera - vars: - mariadb_galera_primary_node: '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-mariadbgalera-1' - mariadb_wsrep_node_address: "{{ ansible_all_ipv4_addresses[0] }}" - mariadb_version: '10.1' +- hosts: galera pre_tasks: - - set_fact: - mariadb_wsrep_node_address: "{{ ansible_eth1.ipv4.address }}" - when: not is_docker + - name: SET_FACT | Apply some configuration + set_fact: + mariadb_galera_primary_node: '{% if is_docker %}docker-{% else %}vbox-{% endif %}{{ ansible_distribution_release }}-upstream-galera-1' + mariadb_wsrep_node_address: "{{ '127.0.0.1' if is_docker else ansible_eth1.ipv4.address }}" + mariadb_version: '10.1' roles: - ../../ - diff --git a/tests/travis.sh b/tests/travis.sh deleted file mode 100644 index 2b76ab1..0000000 --- a/tests/travis.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/bin/sh - -# Thanks to https://servercheck.in/blog/testing-ansible-roles-travis-ci-github - -DIR=$( dirname $0 ) -INVENTORY_FILE="localhost," -PLAYBOOK="$DIR/travis.yml" - -set -ev - -# Check syntax -ansible-playbook -i $INVENTORY_FILE -c local --syntax-check -vv $PLAYBOOK - -# Check role -ansible-playbook -i $INVENTORY_FILE -c local -e "{ mariadb_vendor: $VENDOR, mariadb_origin: $ORIGIN }" --sudo -vv $PLAYBOOK - -# Check indempotence -ansible-playbook -i $INVENTORY_FILE -c local -e "{ mariadb_vendor: $VENDOR, mariadb_origin: $ORIGIN }" --sudo -vv $PLAYBOOK > idempot.txt -grep -q 'changed=0.*failed=0' idempot.txt \ -&& (echo 'Idempotence test: pass' && exit 0) \ -|| (echo 'Idempotence test: FAIL' && cat idempot.txt && exit 1) diff --git a/tests/travis.yml b/tests/travis.yml deleted file mode 100644 index bb99fb7..0000000 --- a/tests/travis.yml +++ /dev/null @@ -1,15 +0,0 @@ ---- - -- hosts: all - vars: - mariadb_replication_master: true - mariadb_bind_address: '{{ ansible_eth0.ipv4.address }}' - mariadb_galera_members: - - '{{ ansible_eth0.ipv4.address }}' - mariadb_galera_primary_node: 'localhost' - roles: - - ../../ - post_tasks: - - name: TEST | SHELL | Test mysql - shell: mysql -e "SHOW DATABASES;" - changed_when: false