Import role from old project
- lots of improvements and simplifications.
This commit is contained in:
		
							parent
							
								
									c6c2cacd0f
								
							
						
					
					
						commit
						12ebef99b1
					
				|  | @ -0,0 +1,66 @@ | |||
| --- | ||||
| repos: | ||||
|   - repo: https://github.com/pre-commit/pre-commit-hooks | ||||
|     rev: v2.5.0 | ||||
|     hooks: | ||||
|       - id: check-ast | ||||
|       - id: check-case-conflict | ||||
|       - id: check-executables-have-shebangs | ||||
|       - id: check-yaml | ||||
|         name: Check yaml files | ||||
|       - id: debug-statements | ||||
|         name: Check for Python debug statements | ||||
|       - id: trailing-whitespace | ||||
|         name: Check trailing whitespace | ||||
|         args: [--markdown-linebreak-ext=md] | ||||
|   - repo: https://gitlab.com/pycqa/flake8.git | ||||
|     rev: 3.7.9 | ||||
|     hooks: | ||||
|       - id: flake8 | ||||
|         name: Check python (flake8) | ||||
|         args: ["--ignore=E501"] | ||||
|   - repo: https://github.com/adrienverge/yamllint.git | ||||
|     rev: v1.23.0 | ||||
|     hooks: | ||||
|       - id: yamllint | ||||
|         name: Check yaml files (yamllint) | ||||
|   - repo: https://github.com/ansible/ansible-lint.git | ||||
|     rev: v4.3.0a0 | ||||
|     hooks: | ||||
|       - id: ansible-lint | ||||
|         name: Check yaml files (ansible-lint) | ||||
|         args: ["-x", "602"] | ||||
|         types: [yaml] | ||||
|   - repo: local | ||||
|     hooks: | ||||
|       - id: docker-markdownlint | ||||
|         name: Run markdownlint with docker | ||||
|         entry: markdownlint/markdownlint -r "~MD013" | ||||
|         language: docker_image | ||||
|         types: [markdown] | ||||
|       - id: docker-shell-shfmt | ||||
|         name: Run shfmt with docker | ||||
|         entry: mvdan/shfmt:latest -d -i 2 -ci | ||||
|         language: docker_image | ||||
|         types: [shell] | ||||
|       - id: docker-shell-lint | ||||
|         name: Run shellcheck with docker | ||||
|         language: docker_image | ||||
|         entry: koalaman/shellcheck:stable | ||||
|         types: [shell] | ||||
|       - id: docker-prettier | ||||
|         name: Run prettier with docker | ||||
|         entry: tmknom/prettier:latest -l | ||||
|         language: docker_image | ||||
|         files: "\\.(\ | ||||
|           css|less|scss\ | ||||
|           |graphql|gql\ | ||||
|           |html\ | ||||
|           |js|jsx\ | ||||
|           |json\ | ||||
|           |md|markdown|mdown|mkdn\ | ||||
|           |mdx\ | ||||
|           |ts|tsx\ | ||||
|           |vue\ | ||||
|           |yaml|yml\ | ||||
|           )$" | ||||
|  | @ -0,0 +1,37 @@ | |||
| --- | ||||
| language: python | ||||
| services: docker | ||||
| 
 | ||||
| env: | ||||
|   global: | ||||
|     - ROLE_NAME: mariadb | ||||
|   matrix: | ||||
|     - MOLECULE_DISTRO: debian-10 | ||||
|     - MOLECULE_DISTRO: debian-sid | ||||
|     - MOLECULE_DISTRO: ubuntu-18.04 | ||||
|     - MOLECULE_DISTRO: ubuntu-20.04 | ||||
| 
 | ||||
| cache: | ||||
|   directories: | ||||
|     - $HOME/.cache/pre-commit | ||||
| 
 | ||||
| install: | ||||
|   - pip3 install -r requirements.txt | ||||
| 
 | ||||
| jobs: | ||||
|   include: | ||||
|     - name: lint with pre-commit | ||||
|       install: skip | ||||
|       script: | ||||
|         - pip3 install pre-commit | ||||
|         - pre-commit run -c .travis-pre-commit-config.yaml -a | ||||
| 
 | ||||
| script: | ||||
|   - export ANSIBLE_STRATEGY=mitogen_linear | ||||
|   - export ANSIBLE_STRATEGY_PLUGINS=${VIRTUAL_ENV}/lib/python${TRAVIS_PYTHON_VERSION}/site-packages/ansible_mitogen/plugins/strategy | ||||
|   - molecule --version | ||||
|   - molecule test | ||||
| # | ||||
| # //TEMP import later to galaxy | ||||
| # notifications: | ||||
| #  webhooks: https://galaxy.ansible.com/api/v1/notifications/ | ||||
|  | @ -0,0 +1,7 @@ | |||
| --- | ||||
| extends: default | ||||
| ignore: | | ||||
|   .direnv | ||||
| rules: | ||||
|   line-length: { max: 200, level: warning } | ||||
|   braces: { min-spaces-inside: 1, max-spaces-inside: 1 } | ||||
|  | @ -0,0 +1,8 @@ | |||
| venv: | ||||
| 	pip3 install -r requirements.txt | ||||
| 
 | ||||
| venv_upgrade: | ||||
| 	for i in $$(cat requirements.txt|cut -d "=" -f1); do pip3 install $$i -U; done | ||||
| 
 | ||||
| test: | ||||
| 	molecule test | ||||
							
								
								
									
										239
									
								
								README.md
								
								
								
								
							
							
						
						
									
										239
									
								
								README.md
								
								
								
								
							|  | @ -1,2 +1,237 @@ | |||
| # ansible-role-mariadb | ||||
| Ansible Role: MariaDB | ||||
| # Ansible role: MariaDB | ||||
| 
 | ||||
| [](https://travis-ci.org/fauust/ansible-role-mariadb) | ||||
| 
 | ||||
| Install and configure MariaDB server on Debian/Ubuntu. | ||||
| 
 | ||||
| Optionally, this role also permits to: | ||||
| 
 | ||||
| - deploy a master/slave cluster; | ||||
| - setup backups and rotation of the dumps. | ||||
| 
 | ||||
| ## Requirements | ||||
| 
 | ||||
| The role use | ||||
| [`mysql_user`](https://docs.ansible.com/ansible/latest/modules/mysql_user_module.html) | ||||
| and | ||||
| [`mysql_db`](https://docs.ansible.com/ansible/latest/modules/mysql_db_module.html) | ||||
| ansible modules that depends on [PyMySQL](https://github.com/PyMySQL/PyMySQL) so | ||||
| the following Python 2.7 or Python 3.X versions are needed. | ||||
| 
 | ||||
| For older Python versions, you may use | ||||
| [MySQLdb](http://mysql-python.sourceforge.net/MySQLdb.html) but then the role | ||||
| may not be idempotent (not tested). | ||||
| 
 | ||||
| ## Fact gathering (performance) | ||||
| 
 | ||||
| Unless you want to use the MariaDB official repository (and then need | ||||
| `ansible_distribution_version`, see [`tasks/setup.yml`](./tasks/setup.yml)) this | ||||
| role does not require fact gathering. | ||||
| 
 | ||||
| ## Role variables | ||||
| 
 | ||||
| Available variables are listed below, along with default values (see | ||||
| [`defaults/main.yml`](./defaults/main.yml)): | ||||
| 
 | ||||
| ### MariaDB version | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_use_official_repo: false | ||||
| mariadb_use_official_repo_url: "http://ftp.igh.cnrs.fr/pub/mariadb/repo" | ||||
| mariadb_use_official_repo_version: "10.4" | ||||
| ``` | ||||
| 
 | ||||
| You may deploy the MariaDB Server version that comes with your distribution (Debian/Ubuntu) or | ||||
| deploy the version packaged by the MariaDB Foundation. | ||||
| You will find the repositories URL here: | ||||
| <https://downloads.mariadb.org/mariadb/repositories/> | ||||
| 
 | ||||
| By default we deploy the MariaDB Server version that comes with the distribution. | ||||
| 
 | ||||
| ### MariaDB service activation and restart | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_enabled_on_startup: true | ||||
| mariadb_can_restart: true | ||||
| ``` | ||||
| 
 | ||||
| **Warning:** you may consider setting `mariadb_can_restart` to `false` on | ||||
| production systems to prevent ansible runs to restart the MariaDB server. | ||||
| 
 | ||||
| ### General configuration | ||||
| 
 | ||||
| To populate the MariaDB Server configuration file, we use almost only raw | ||||
| variables. This permits more flexibility and a very simple | ||||
| [`templates/my.cnf.j2`](./templates/my.cnf.j2) file. | ||||
| 
 | ||||
| By default, some common and standard options are deployed. | ||||
| 
 | ||||
| #### Basic settings | ||||
| 
 | ||||
| The following variables are also needed by playbooks so we can not use raw | ||||
| variables. | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_config_file: /etc/mysql/my.cnf | ||||
| mariadb_datadir: "/var/lib/mysql" | ||||
| mariadb_port: "3306" | ||||
| mariadb_bind_address: "127.0.0.1" | ||||
| mariadb_unix_socket: "/run/mysqld/mysqld.sock" | ||||
| ``` | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_basic_settings_raw: | | ||||
|   user                  = mysql | ||||
|   pid-file              = /run/mysqld/mysqld.pid | ||||
|   socket                = {{ mariadb_unix_socket }} | ||||
|   basedir               = /usr | ||||
|   datadir               = {{ mariadb_datadir }} | ||||
|   tmpdir                = /tmp | ||||
|   lc-messages-dir       = /usr/share/mysql | ||||
|   lc_messages           = en_US | ||||
|   skip-external-locking | ||||
|   port                  = {{ mariadb_port }} | ||||
|   bind-address          = {{ mariadb_bind_address }} | ||||
| ``` | ||||
| 
 | ||||
| #### Fine tuning | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_fine_tuning_raw: | | ||||
|   max_connections         = 100 | ||||
|   connect_timeout         = 5 | ||||
|   wait_timeout            = 600 | ||||
|   max_allowed_packet      = 16M | ||||
|   thread_cache_size       = 128 | ||||
|   sort_buffer_size        = 4M | ||||
|   bulk_insert_buffer_size = 16M | ||||
|   tmp_table_size          = 32M | ||||
|   max_heap_table_size     = 32M | ||||
| ``` | ||||
| 
 | ||||
| #### Query cache | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_query_cache_raw: | | ||||
|   query_cache_size        = 16M | ||||
| ``` | ||||
| 
 | ||||
| #### Logging | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_logging_raw: | | ||||
|   log_error = /var/log/mysql/error.log | ||||
| ``` | ||||
| 
 | ||||
| #### Character sets | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_character_sets_raw: | | ||||
|   character-set-server = utf8mb4 | ||||
|   collation-server     = utf8mb4_general_ci | ||||
| ``` | ||||
| 
 | ||||
| #### InnoDB | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_innodb_raw: | | ||||
|   # InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/. | ||||
|   # Read the manual for more InnoDB related options. There are many! | ||||
| ``` | ||||
| 
 | ||||
| #### Mariadbdump | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_mysqldump_raw: | | ||||
|   quick | ||||
|   quote-names | ||||
|   max_allowed_packet = 16M | ||||
| ``` | ||||
| 
 | ||||
| ### Databases management | ||||
| 
 | ||||
| ```yaml | ||||
| # Databases. | ||||
| mariadb_databases: [] | ||||
| #   - name: db1 | ||||
| #     collation: utf8_general_ci | ||||
| #     encoding: utf8 | ||||
| #     replicate: true|false | ||||
| ``` | ||||
| 
 | ||||
| See: <https://docs.ansible.com/ansible/latest/modules/mysql_db_module.html> | ||||
| 
 | ||||
| ### Users management | ||||
| 
 | ||||
| ```yaml | ||||
| # Users. | ||||
| mariadb_users: [] | ||||
| #   - name: user | ||||
| #     host: 100.64.200.10 | ||||
| #     password: password | ||||
| #     priv: "*.*:USAGE/db1.*:ALL" | ||||
| #     state: present|absent | ||||
| ``` | ||||
| 
 | ||||
| See: <https://docs.ansible.com/ansible/latest/modules/mysql_user_module.html> | ||||
| 
 | ||||
| ### Replication (optional) | ||||
| 
 | ||||
| Replication is only enabled if `mariadb_replication_role` has a value (`master` or | ||||
| `slave`). | ||||
| 
 | ||||
| The replication setup on the slave use the GTID autopositionning | ||||
| `master_use_gtid=slave_pos`. See: | ||||
| <https://mariadb.com/kb/en/library/change-master-to/#master_use_gtid> | ||||
| 
 | ||||
| For the moment, we use an `SQL` command but in ansible 2.10, we should be able | ||||
| to use the | ||||
| [`mysql_replication`](https://docs.ansible.com/ansible/latest/modules/mysql_replication_module.html) | ||||
| module (see | ||||
| [`tasks/replication_slave.yml`](./tasks/replication_slave.yml#L09-L33) and | ||||
| <https://github.com/ansible/ansible/pull/62648>). | ||||
| 
 | ||||
| ```yaml | ||||
| mariadb_replication_role: "" # master|slave | ||||
| mariadb_replication_master_ip: "" | ||||
| mariadb_server_id: "1" | ||||
| mariadb_max_binlog_size: "100M" | ||||
| mariadb_binlog_format: "MIXED" | ||||
| mariadb_expire_logs_days: "10" | ||||
| 
 | ||||
| # Same keys as `mariadb_users` above. | ||||
| # priv is set to "*.*:REPLICATION SLAVE" by default | ||||
| mariadb_replication_user: [] | ||||
| ``` | ||||
| 
 | ||||
| ### Backups (optional) | ||||
| 
 | ||||
| ```yaml | ||||
| # db dumps backup | ||||
| mariadb_backup_db: false | ||||
| mariadb_backup_db_cron_min: "50" | ||||
| mariadb_backup_db_cron_hour: "00" | ||||
| mariadb_backup_db_dir: "/mnt/backup" | ||||
| mariadb_backup_db_rotation: "15" | ||||
| 
 | ||||
| # name of the database to dump | ||||
| # (mandatory if mariadb_backup_db is set to true) | ||||
| mariadb_backup_db_name: [] | ||||
| #   - db1 | ||||
| #   - db2 | ||||
| ``` | ||||
| 
 | ||||
| Database dump is done serially and compression (`gzip`) is done at the end to | ||||
| avoid too long locks. | ||||
| 
 | ||||
| ## Example Playbook | ||||
| 
 | ||||
| ```yaml | ||||
| - hosts: database | ||||
|   roles: | ||||
|     - fauust.mariadb | ||||
| ``` | ||||
| 
 | ||||
| ## Lincense | ||||
| 
 | ||||
| GNU General Public License v3.0 | ||||
|  |  | |||
|  | @ -0,0 +1,110 @@ | |||
| --- | ||||
| # Configure the following to use official MariaDB repository | ||||
| # see: https://downloads.mariadb.org/mariadb/repositories | ||||
| mariadb_use_official_repo: false | ||||
| mariadb_use_official_repo_url: "http://ftp.igh.cnrs.fr/pub/mariadb/repo" | ||||
| mariadb_use_official_repo_version: "10.4" | ||||
| 
 | ||||
| mariadb_enabled_on_startup: true | ||||
| # The following is set to true by default but you may consider setting it to | ||||
| # false on production servers to prevent ansible from restarting mariadb server. | ||||
| mariadb_can_restart: true | ||||
| 
 | ||||
| # Whether global conf file should be updated on every run | ||||
| mariadb_overwrite_global_config_file: true | ||||
| 
 | ||||
| # MariaDB configuration file | ||||
| mariadb_config_file: /etc/mysql/my.cnf | ||||
| # Basic settings | ||||
| mariadb_datadir: "/var/lib/mysql" | ||||
| mariadb_port: "3306" | ||||
| mariadb_bind_address: "127.0.0.1" | ||||
| mariadb_unix_socket: "/run/mysqld/mysqld.sock" | ||||
| mariadb_basic_settings_raw: | | ||||
|   user                  = mysql | ||||
|   pid-file              = /run/mysqld/mysqld.pid | ||||
|   socket                = {{ mariadb_unix_socket }} | ||||
|   basedir               = /usr | ||||
|   datadir               = {{ mariadb_datadir }} | ||||
|   tmpdir                = /tmp | ||||
|   lc-messages-dir       = /usr/share/mysql | ||||
|   lc_messages           = en_US | ||||
|   skip-external-locking | ||||
|   port                  = {{ mariadb_port }} | ||||
|   bind-address          = {{ mariadb_bind_address }} | ||||
| 
 | ||||
| # Fine tuning | ||||
| mariadb_fine_tuning_raw: | | ||||
|   max_connections         = 100 | ||||
|   connect_timeout         = 5 | ||||
|   wait_timeout            = 600 | ||||
|   max_allowed_packet      = 16M | ||||
|   thread_cache_size       = 128 | ||||
|   sort_buffer_size        = 4M | ||||
|   bulk_insert_buffer_size = 16M | ||||
|   tmp_table_size          = 32M | ||||
|   max_heap_table_size     = 32M | ||||
| 
 | ||||
| # Query cache | ||||
| mariadb_query_cache_raw: | | ||||
|   query_cache_size        = 16M | ||||
| 
 | ||||
| # Logging | ||||
| mariadb_logging_raw: | | ||||
|   log_error = /var/log/mysql/error.log | ||||
| 
 | ||||
| # Character sets | ||||
| mariadb_character_sets_raw: | | ||||
|   character-set-server = utf8mb4 | ||||
|   collation-server     = utf8mb4_general_ci | ||||
| 
 | ||||
| # InnoDB | ||||
| mariadb_innodb_raw: | | ||||
|   # InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/. | ||||
|   # Read the manual for more InnoDB related options. There are many! | ||||
| 
 | ||||
| # mariadbdump | ||||
| mariadb_mysqldump_raw: | | ||||
|   quick | ||||
|   quote-names | ||||
|   max_allowed_packet = 16M | ||||
| 
 | ||||
| # Databases | ||||
| mariadb_databases: [] | ||||
| #   - name: db1 | ||||
| #     collation: utf8_general_ci | ||||
| #     encoding: utf8 | ||||
| #     replicate: true|false | ||||
| 
 | ||||
| # Users | ||||
| mariadb_users: [] | ||||
| #   - name: user | ||||
| #     host: 100.64.200.10 | ||||
| #     password: password | ||||
| #     priv: "*.*:USAGE/db1.*:ALL" | ||||
| #     state: present|absent | ||||
| 
 | ||||
| # Replication | ||||
| # replication is only enabled if mariadb_replication_role has values | ||||
| mariadb_replication_role: "" # master|slave | ||||
| mariadb_replication_master_ip: "" | ||||
| mariadb_max_binlog_size: "100M" | ||||
| mariadb_binlog_format: "MIXED" | ||||
| mariadb_expire_logs_days: "10" | ||||
| 
 | ||||
| # Replication users | ||||
| # same keys as mariadb_users above | ||||
| # priv is set to "*.*:REPLICATION SLAVE" by default | ||||
| mariadb_replication_user: [] | ||||
| 
 | ||||
| # Backups | ||||
| mariadb_backup_db: false | ||||
| mariadb_backup_db_cron_min: "50" | ||||
| mariadb_backup_db_cron_hour: "00" | ||||
| mariadb_backup_db_dir: "/opt/backup" | ||||
| mariadb_backup_db_rotation: "15" | ||||
| 
 | ||||
| # DB to backup | ||||
| mariadb_backup_db_name: [] | ||||
| #   - db1 | ||||
| #   - db2 | ||||
|  | @ -0,0 +1,103 @@ | |||
| #!/usr/bin/env bash | ||||
| 
 | ||||
| set -o errexit | ||||
| set -o pipefail | ||||
| set -o nounset | ||||
| set -o posix | ||||
| 
 | ||||
| err() { | ||||
|   echo >&2 "[$(date +'%Y-%m-%dT%H:%M:%S%z')] ERROR: $*" | ||||
| } | ||||
| 
 | ||||
| usage() { | ||||
|   cat >&2 <<-EOF | ||||
| Usage : $0 -d <directory> -l <db_name> | ||||
|   -d dump directory destination (mandatory) | ||||
|   -l list of db to dump (coma separated, mandatory) | ||||
|   -k dumps to keep (in days) | ||||
|   -h help | ||||
| EOF | ||||
| } | ||||
| 
 | ||||
| typeset VAR_DIR_ARGS="" | ||||
| typeset VAR_DB_LIST_ARGS="" | ||||
| typeset VAR_ROTATION_DAYS_ARGS="" | ||||
| 
 | ||||
| while getopts "d:l:k:h" OPTION; do | ||||
|   case $OPTION in | ||||
|     d) | ||||
|       VAR_DIR_ARGS="$OPTARG" | ||||
|       ;; | ||||
|     l) | ||||
|       VAR_DB_LIST_ARGS="$OPTARG" | ||||
|       ;; | ||||
|     k) | ||||
|       VAR_ROTATION_DAYS_ARGS="$OPTARG" | ||||
|       ;; | ||||
|     h) | ||||
|       usage | ||||
|       exit 0 | ||||
|       ;; | ||||
|     *) | ||||
|       usage | ||||
|       exit 1 | ||||
|       ;; | ||||
|   esac | ||||
| done | ||||
| 
 | ||||
| [[ $VAR_DIR_ARGS != "" ]] || { | ||||
|   usage | ||||
|   exit 1 | ||||
| } | ||||
| [[ $VAR_DB_LIST_ARGS != "" ]] || { | ||||
|   usage | ||||
|   exit 1 | ||||
| } | ||||
| 
 | ||||
| # remove eventual trailing slash | ||||
| typeset -r VAR_DUMPS_DST_DIR=${VAR_DIR_ARGS%/} | ||||
| 
 | ||||
| if [[ ! -d $VAR_DUMPS_DST_DIR ]]; then | ||||
|   mkdir -p "$VAR_DUMPS_DST_DIR" || { | ||||
|     err "mkdir -p $VAR_DUMPS_DST_DIR" | ||||
|     exit 1 | ||||
|   } | ||||
| fi | ||||
| 
 | ||||
| for cmd in mysqldump gzip; do | ||||
|   command -v "$cmd" >/dev/null || { | ||||
|     err "$cmd command not found" | ||||
|     exit 1 | ||||
|   } | ||||
| done | ||||
| 
 | ||||
| for db in ${VAR_DB_LIST_ARGS//,/ }; do | ||||
|   echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: start $db dump." | ||||
|   typeset DUMP_FILE=$VAR_DUMPS_DST_DIR/$db.$(date +%F_%H%M%S).sql | ||||
|   mysqldump --single-transaction --quick --routines "$db" >"$DUMP_FILE" | ||||
|   # shellcheck disable=SC2181 | ||||
|   if (($? != 0)); then | ||||
|     err "unable do dump $db" | ||||
|     exit 1 | ||||
|   fi | ||||
|   echo -e "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: done.\n" | ||||
| done | ||||
| 
 | ||||
| for sql in "$VAR_DUMPS_DST_DIR/"*.sql; do | ||||
|   echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: compress $sql." | ||||
|   gzip -- "$sql" || { | ||||
|     err "gzip $sql" | ||||
|     exit 1 | ||||
|   } | ||||
|   echo -e "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: done.\n" | ||||
| done | ||||
| 
 | ||||
| if [[ -n $VAR_ROTATION_DAYS_ARGS ]]; then | ||||
|   # rotation | ||||
|   echo "Rotation of old dumps (-${VAR_ROTATION_DAYS_ARGS}d)" | ||||
|   if ! find "$VAR_DUMPS_DST_DIR" -name "*.sql.gz" -type f -mtime +"$((VAR_ROTATION_DAYS_ARGS - 1))" -exec /bin/rm -vf {} \;; then | ||||
|     err "clean old dumps" | ||||
|     exit 1 | ||||
|   fi | ||||
|   echo -e "done.\n" | ||||
| fi | ||||
|  | @ -0,0 +1,8 @@ | |||
| --- | ||||
| - name: restart mariadb | ||||
|   service: | ||||
|     name: mariadb | ||||
|     state: restarted | ||||
|   when: | ||||
|     - mariadb_can_restart | ||||
|     - not ansible_check_mode | ||||
|  | @ -0,0 +1,21 @@ | |||
| --- | ||||
| dependencies: [] | ||||
| 
 | ||||
| galaxy_info: | ||||
|   author: fauust | ||||
|   role_name: mariadb | ||||
|   description: MariaDB server for Debian/Ubuntu. | ||||
|   license: "license GPL-3.0-only" | ||||
|   min_ansible_version: 2.8 | ||||
|   platforms: | ||||
|     - name: Debian | ||||
|       versions: | ||||
|         - buster | ||||
|         - sid | ||||
|     - name: Ubuntu | ||||
|       versions: | ||||
|         - bionic | ||||
|         - focal | ||||
|   galaxy_tags: | ||||
|     - mariadb | ||||
|     - mysql | ||||
|  | @ -0,0 +1,14 @@ | |||
| --- | ||||
| - name: Converge | ||||
|   hosts: all | ||||
|   gather_facts: true | ||||
|   vars: | ||||
|     ansible_python_interpreter: /usr/bin/python3 | ||||
|   vars_files: testvars.yml | ||||
| 
 | ||||
|   pre_tasks: | ||||
|     - name: Update apt cache | ||||
|       apt: update_cache=true cache_valid_time=600 | ||||
| 
 | ||||
|   roles: | ||||
|     - role: ansible-role-mariadb | ||||
|  | @ -0,0 +1,20 @@ | |||
| --- | ||||
| dependency: | ||||
|   name: galaxy | ||||
| driver: | ||||
|   name: docker | ||||
| platforms: | ||||
|   - name: instance | ||||
|     image: "fauust/docker-ansible:${MOLECULE_DISTRO:-debian-10}" | ||||
|     volumes: | ||||
|       - /sys/fs/cgroup:/sys/fs/cgroup:ro | ||||
|     privileged: true | ||||
|     command: /lib/systemd/systemd | ||||
| provisioner: | ||||
|   name: ansible | ||||
|   env: | ||||
|     ANSIBLE_GATHERING: explicit | ||||
|     ANSIBLE_FORCE_COLOR: true | ||||
|     ANSIBLE_PYTHON_INTERPRETER: /usr/bin/python3 | ||||
| verifier: | ||||
|   name: testinfra | ||||
|  | @ -0,0 +1,69 @@ | |||
| import os | ||||
| 
 | ||||
| import testinfra.utils.ansible_runner | ||||
| 
 | ||||
| testinfra_hosts = testinfra.utils.ansible_runner.AnsibleRunner( | ||||
|     os.environ['MOLECULE_INVENTORY_FILE']).get_hosts('all') | ||||
| 
 | ||||
| 
 | ||||
| def test_passwd_file(host): | ||||
|     passwd = host.file("/etc/passwd") | ||||
|     assert passwd.contains("mysql") | ||||
|     assert passwd.user == "root" | ||||
|     assert passwd.group == "root" | ||||
| 
 | ||||
| 
 | ||||
| def test_mariadb_is_installed(host): | ||||
|     package = host.package("mariadb-server") | ||||
|     assert package.is_installed | ||||
| 
 | ||||
| 
 | ||||
| def test_ensure_mariadb_is_listening_on_requiered_port(host): | ||||
|     assert host.socket("tcp://0.0.0.0:3306").is_listening | ||||
| 
 | ||||
| 
 | ||||
| def test_mariadb_enabled_and_running(host): | ||||
|     assert host.service("mariadb").is_running | ||||
|     assert host.service("mariadb").is_enabled | ||||
| 
 | ||||
| 
 | ||||
| def test_ensure_custom_config_is_applied(host): | ||||
|     config = host.file("/etc/mysql/my.cnf") | ||||
|     assert config.contains("datadir") | ||||
|     assert config.user == "root" | ||||
|     assert config.group == "root" | ||||
|     assert config.mode == 0o644 | ||||
| 
 | ||||
| 
 | ||||
| def test_ensure_innodb_is_enabled(host): | ||||
|     assert host.run("mariadb -Bse 'SHOW ENGINES' |\ | ||||
|             grep -qE '^InnoDB.DEFAULT.*YES.YES.YES$'").rc == 0 | ||||
| 
 | ||||
| 
 | ||||
| def test_ensure_system_db_exist(host): | ||||
|     assert host.run("mariadb -Bse 'SHOW DATABASES' |\ | ||||
|             grep -q '^mysql$'").rc == 0 | ||||
|     assert host.run("mariadb -Bse 'SHOW DATABASES' |\ | ||||
|             grep -q '^information_schema$'").rc == 0 | ||||
|     assert host.run("mariadb -Bse 'SHOW DATABASES' |\ | ||||
|             grep -q '^performance_schema$'").rc == 0 | ||||
| 
 | ||||
| 
 | ||||
| def test_ensure_test_db_exist(host): | ||||
|     assert host.run("mariadb -Bse 'SHOW DATABASES' |\ | ||||
|             grep -q '^db1'").rc == 0 | ||||
|     assert host.run("mariadb -Bse 'SHOW DATABASES' |\ | ||||
|             grep -q '^db2'").rc == 0 | ||||
| 
 | ||||
| 
 | ||||
| def test_some_sql_queries(host): | ||||
|     assert host.run("mariadb -e 'CREATE DATABASE db'").rc == 0 | ||||
|     assert host.run("mariadb -e 'CREATE TABLE\ | ||||
|             db.t_innodb(a1 SERIAL, c1 CHAR(8)) ENGINE=InnoDB;\ | ||||
|             INSERT INTO db.t_innodb VALUES (1,\"foo\"),(2,\"bar\")'").rc == 0 | ||||
|     assert host.run("mariadb -e 'CREATE FUNCTION db.f()\ | ||||
|             RETURNS INT DETERMINISTIC RETURN 1'").rc == 0 | ||||
|     assert host.run("mariadb -e 'SHOW TABLES IN db'").rc == 0 | ||||
|     assert host.run("mariadb -e 'SELECT * FROM db.t_innodb;\ | ||||
|             INSERT INTO db.t_innodb VALUES (3,\"foo\"),(4,\"bar\")'").rc == 0 | ||||
|     assert host.run("mariadb -e 'SELECT db.f()'").rc == 0 | ||||
|  | @ -0,0 +1,47 @@ | |||
| --- | ||||
| mariadb_server_id: 1 | ||||
| mariadb_bind_address: 0.0.0.0 | ||||
| mariadb_replication_role: master | ||||
| 
 | ||||
| mariadb_innodb_raw: | | ||||
|   innodb_buffer_pool_size = 512M | ||||
|   innodb_log_file_size  = 64M | ||||
|   innodb_file_per_table = 1 | ||||
| 
 | ||||
| mariadb_databases: | ||||
|   - name: db1 | ||||
|     collation: latin1_swedish_ci | ||||
|     encoding: latin1 | ||||
|     state: present | ||||
|   - name: db2 | ||||
|     state: present | ||||
|     replicate: true | ||||
| 
 | ||||
| mariadb_users: | ||||
|   - name: user1 | ||||
|     host: "%" | ||||
|     password: user1passwd | ||||
|     priv: "db2.*:SELECT" | ||||
|     state: present | ||||
|   - name: user2 | ||||
|     host: 100.64.10.3 | ||||
|     password: user2passwd | ||||
|     priv: "db2.*:ALL" | ||||
|     state: present | ||||
| 
 | ||||
| mariadb_replication_user: | ||||
|   - name: ReplicationUser | ||||
|     host: 100.64.10.33 | ||||
|     password: ReplicationPassword | ||||
|     state: present | ||||
| 
 | ||||
| # backup | ||||
| mariadb_backup_db: true | ||||
| mariadb_backup_db_cron_min: "50" | ||||
| mariadb_backup_db_cron_hour: "00" | ||||
| mariadb_backup_db_dir: "/mnt/backup" | ||||
| mariadb_backup_db_rotation: "15" | ||||
| 
 | ||||
| mariadb_backup_db_name: | ||||
|   - db1 | ||||
|   - db2 | ||||
|  | @ -0,0 +1,8 @@ | |||
| ansible-lint==4.2.0 | ||||
| ansible==2.9.9 | ||||
| docker==4.2.0 | ||||
| flake8==3.8.1 | ||||
| mitogen==0.2.9 | ||||
| molecule==3.0.4 | ||||
| testinfra==5.0.0 | ||||
| yamllint==1.23.0 | ||||
|  | @ -0,0 +1,36 @@ | |||
| --- | ||||
| - name: Install cron package | ||||
|   apt: | ||||
|     package: | ||||
|       - cron | ||||
|     state: present | ||||
| 
 | ||||
| - name: Deploy DB dump script | ||||
|   copy: | ||||
|     src: mariadb_dump_db.sh | ||||
|     dest: /usr/local/bin/mariadb_dump_db.sh | ||||
|     owner: root | ||||
|     group: root | ||||
|     mode: 0744 | ||||
|     validate: "bash -n %s" | ||||
| 
 | ||||
| - name: Ensure backup dir exists | ||||
|   file: | ||||
|     path: "{{ mariadb_backup_db_dir }}" | ||||
|     state: directory | ||||
|     owner: root | ||||
|     group: root | ||||
|     mode: 0755 | ||||
| 
 | ||||
| - name: Deploy crontab file | ||||
|   cron: | ||||
|     name: "Dump MariaBD databases" | ||||
|     minute: "{{ mariadb_backup_db_cron_min }}" | ||||
|     hour: "{{ mariadb_backup_db_cron_hour }}" | ||||
|     job: "/usr/local/bin/mariadb_dump_db.sh \ | ||||
|       -d \"{{ mariadb_backup_db_dir }}\" \ | ||||
|       -l \"{{ mariadb_backup_db_name|join(',') }}\" \ | ||||
|       -k {{ mariadb_backup_db_rotation }} \ | ||||
|       >{{ mariadb_backup_db_dir }}/mariadb_dump_db.log 2>&1" | ||||
|     cron_file: mariadb_dump_db | ||||
|     user: root | ||||
|  | @ -0,0 +1,28 @@ | |||
| --- | ||||
| - name: Copy global MariaDB configuration | ||||
|   template: | ||||
|     src: my.cnf.j2 | ||||
|     dest: "{{ mariadb_config_file }}" | ||||
|     owner: root | ||||
|     group: root | ||||
|     mode: 0644 | ||||
|     force: "{{ mariadb_overwrite_global_config_file }}" | ||||
|   notify: restart mariadb | ||||
| 
 | ||||
| - name: Create datadir if it does not exist | ||||
|   file: | ||||
|     path: "{{ mariadb_datadir }}" | ||||
|     state: directory | ||||
|     owner: mysql | ||||
|     group: mysql | ||||
|     mode: 0755 | ||||
| 
 | ||||
| - name: Ensure MariaDB is started and enabled on boot | ||||
|   service: | ||||
|     name: mariadb | ||||
|     state: started | ||||
|     enabled: "{{ mariadb_enabled_on_startup }}" | ||||
| 
 | ||||
| # immediately restart mariadb | ||||
| # this is necessary for replication setup | ||||
| - meta: flush_handlers | ||||
|  | @ -0,0 +1,9 @@ | |||
| --- | ||||
| - name: Ensure MariaDB databases are present (or absent) | ||||
|   mysql_db: | ||||
|     name: "{{ item.name }}" | ||||
|     collation: "{{ item.collation | default('utf8_general_ci') }}" | ||||
|     encoding: "{{ item.encoding | default('utf8') }}" | ||||
|     state: "{{ item.state | default('present') }}" | ||||
|     login_unix_socket: "{{ mariadb_unix_socket | default ('/run/mysqld/mysqld.sock') }}" | ||||
|   with_items: "{{ mariadb_databases }}" | ||||
|  | @ -0,0 +1,32 @@ | |||
| --- | ||||
| - name: include task setup.yml | ||||
|   include_tasks: setup.yml | ||||
| 
 | ||||
| - name: include task configure.yml | ||||
|   include_tasks: configure.yml | ||||
| 
 | ||||
| - name: include task databases.yml | ||||
|   include_tasks: databases.yml | ||||
|   when: | ||||
|     - mariadb_databases is defined | ||||
|     - mariadb_replication_role != "slave" | ||||
| 
 | ||||
| - name: include task users.yml | ||||
|   include_tasks: users.yml | ||||
|   when: | ||||
|     - mariadb_users is defined | ||||
|     - mariadb_replication_role != "slave" | ||||
| 
 | ||||
| - name: include task replication_master.yml | ||||
|   include_tasks: replication_master.yml | ||||
|   when: mariadb_replication_role == "master" | ||||
| 
 | ||||
| - name: include task replication_slave.yml | ||||
|   include_tasks: replication_slave.yml | ||||
|   when: | ||||
|     - not ansible_check_mode | ||||
|     - mariadb_replication_role == "slave" | ||||
| 
 | ||||
| - name: include task backup.yml | ||||
|   include_tasks: backup.yml | ||||
|   when: mariadb_backup_db | ||||
|  | @ -0,0 +1,12 @@ | |||
| --- | ||||
| - name: Ensure replication user exists on master | ||||
|   mysql_user: | ||||
|     name: "{{ item.name }}" | ||||
|     host: "{{ item.host | default('%') }}" | ||||
|     password: "{{ item.password }}" | ||||
|     priv: "{{ item.priv | default('*.*:REPLICATION SLAVE') }}" | ||||
|     state: present | ||||
|     login_unix_socket: "{{ mariadb_unix_socket }}" | ||||
|   with_items: "{{ mariadb_replication_user }}" | ||||
|   when: not ansible_check_mode | ||||
|   no_log: true | ||||
|  | @ -0,0 +1,54 @@ | |||
| --- | ||||
| - name: Check slave replication status | ||||
|   mysql_replication: | ||||
|     mode: getslave | ||||
|     login_unix_socket: "{{ mariadb_unix_socket }}" | ||||
|   register: slave | ||||
|   no_log: true | ||||
| 
 | ||||
| # For the moment, we have to use a sql command. | ||||
| # In ansible 2.10, we should be able to use mysql_replication module. | ||||
| # See https://github.com/ansible/ansible/pull/62648 (and below) | ||||
| - name: Configure replication on the slave | ||||
|   command: | | ||||
|     /usr/bin/mariadb -e "CHANGE MASTER TO master_host='{{ mariadb_replication_master_ip }}', | ||||
|     master_user='{{ item.name }}', master_password='{{ item.password }}', master_use_gtid=slave_pos" | ||||
|   with_items: "{{ mariadb_replication_user }}" | ||||
|   when: | ||||
|     - not slave.Is_Slave | ||||
|   no_log: true | ||||
| 
 | ||||
| # # Following (not tested) should work on ansible 2.10 | ||||
| # - name: Configure replication on the slave | ||||
| #   mysql_replication: | ||||
| #     mode: changemaster | ||||
| #     master_host: "{{ mariadb_replication_master_ip }}" | ||||
| #     master_user: "{{ item.name }}" | ||||
| #     master_password: "{{ item.password }}" | ||||
| #     master_use_gtid: "{{ mariadb_replication_gtid | default('slave_pos') }} | ||||
| #     login_unix_socket: "{{ mariadb_unix_socket }}" | ||||
| #   with_items: "{{ mariadb_replication_user }}" | ||||
| #   when: | ||||
| #     - not slave.Is_Slave | ||||
| #   no_log: true | ||||
| 
 | ||||
| - name: Reset slave replication | ||||
|   mysql_replication: | ||||
|     mode: resetslave | ||||
|     login_unix_socket: "{{ mariadb_unix_socket }}" | ||||
|   when: | ||||
|     - not slave.Is_Slave | ||||
| 
 | ||||
| - name: Check slave replication status (second time) | ||||
|   mysql_replication: | ||||
|     mode: getslave | ||||
|     login_unix_socket: "{{ mariadb_unix_socket }}" | ||||
|   register: slave2 | ||||
|   no_log: true | ||||
| 
 | ||||
| - name: Start slave replication | ||||
|   mysql_replication: | ||||
|     mode: startslave | ||||
|     login_unix_socket: "{{ mariadb_unix_socket }}" | ||||
|   when: | ||||
|     - slave2.Slave_IO_Running == "No" | ||||
|  | @ -0,0 +1,36 @@ | |||
| --- | ||||
| - name: Install mariadb repo necessary packages | ||||
|   apt: | ||||
|     package: | ||||
|       - software-properties-common | ||||
|       - dirmngr | ||||
|     state: present | ||||
|   when: mariadb_use_official_repo | ||||
| 
 | ||||
| - name: Install mariadb repository key | ||||
|   apt_key: | ||||
|     keyserver: keyserver.ubuntu.com | ||||
|     id: "0xF1656F24C74CD1D8" | ||||
|   when: mariadb_use_official_repo | ||||
| 
 | ||||
| - name: Setup mariadb repository sourcelist entry | ||||
|   apt_repository: | ||||
|     repo: deb {{ mariadb_use_official_repo_url }}/{{ mariadb_use_official_repo_version }}/debian {{ ansible_distribution_release }} main | ||||
|     state: present | ||||
|   when: mariadb_use_official_repo | ||||
| 
 | ||||
| - name: Install mariadb | ||||
|   apt: | ||||
|     package: | ||||
|       - mariadb-server | ||||
|     state: present | ||||
|     update_cache: true | ||||
| 
 | ||||
| - name: Determine required MariaDB Python libraries | ||||
|   set_fact: | ||||
|     deb_mariadb_python_package: "{% if 'python3' in ansible_python_interpreter|default('') %}python3-pymysql{% else %}python-pymysql{% endif %}" | ||||
| 
 | ||||
| - name: Install python mariadb driver | ||||
|   apt: | ||||
|     name: "{{ deb_mariadb_python_package }}" | ||||
|     state: present | ||||
|  | @ -0,0 +1,13 @@ | |||
| --- | ||||
| - name: Ensure MariaDB users are present (or absent) | ||||
|   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') }}" | ||||
|     login_unix_socket: "{{ mariadb_unix_socket }}" | ||||
|   with_items: "{{ mariadb_users }}" | ||||
|   no_log: true | ||||
|  | @ -0,0 +1,49 @@ | |||
| # {{ ansible_managed }} | ||||
| 
 | ||||
| [mariadb] | ||||
| 
 | ||||
| # Basic settings | ||||
| {{ mariadb_basic_settings_raw }} | ||||
| # Fine tuning | ||||
| {{ mariadb_fine_tuning_raw }} | ||||
| # Logging | ||||
| {{ mariadb_logging_raw }} | ||||
| # Query cache | ||||
| {{ mariadb_query_cache_raw }} | ||||
| # Character sets | ||||
| {{ mariadb_character_sets_raw }} | ||||
| # InnoDB | ||||
| {{ mariadb_innodb_raw }} | ||||
| 
 | ||||
| {% if mariadb_replication_role != '' %} | ||||
| # Replication | ||||
| server-id = {{ mariadb_server_id }} | ||||
| log-basename = mariadb | ||||
| 
 | ||||
| {% if mariadb_replication_role == 'master' %} | ||||
| log_bin | ||||
| expire_logs_days = {{ mariadb_expire_logs_days }} | ||||
| max_binlog_size = {{ mariadb_max_binlog_size }} | ||||
| binlog_format = {{mariadb_binlog_format}} | ||||
| # the following permits to simplify the process of moving a slave to a master | ||||
| # role by ensuring that replication is not started on master | ||||
| skip-slave-start | ||||
| 
 | ||||
| {% for db in mariadb_databases %} | ||||
| {% if db.replicate|default(false) %} | ||||
| binlog_do_db = {{ db.name }} | ||||
| {% else %} | ||||
| binlog_ignore_db = {{ db.name }} | ||||
| {% endif %} | ||||
| {% endfor %} | ||||
| {% endif %} | ||||
| 
 | ||||
| {% if mariadb_replication_role == 'slave' %} | ||||
| read_only | ||||
| relay-log = relay-bin | ||||
| relay-log-index = relay-bin.index | ||||
| {% endif %} | ||||
| {% endif -%} | ||||
| 
 | ||||
| [mysqldump] | ||||
| {{ mariadb_mysqldump_raw }} | ||||
		Loading…
	
		Reference in New Issue