#2.MySQLモジュールについて勉強したこと

# はじめに
今回、AnsibleでMySQLをデプロイする際に、mysql_userモジュールやmysql_dbなどのモジュールを使用して自動化してみたので振り返りを行おうと思います。

# shellモジュールとMySQLモジュール

アンシブルを用いたデータベースの設定の自動化を行う際に、
よくshellモジュールとMySQLモジュールを使用するのを見かけるのですがどちらがいいか考えてみました。

# shellモジュール
- メリット
  - shellコマンドで処理を行うので自由度が高い
  - MySQLのコマンドをそのまま使えるので日常的にデータベースを触れることの多い方は違和感なく使用可能
- デメリット
  - 再度実行した際に冪等性が保たれないのでエラーがでてしまう恐れがある
  - 冪等性を保つためにwhenを使用するなどひと手間がかかる。
※エラー処理を無視する設定としてignore_errorsがあるがこちらはエラーが発生したまま後続の処理を行ってしまうため推奨されない。

# MySQLモジュール
- メリット
  - 冪等性が担保されている。
  - 公式ドキュメントに情報が公開されているので信頼性が高い。
  - 設定がシンプルで覚えやすい。
- デメリット
  - 設定できる項目が限られているため自由度がshellよりも低く、場合によっては要所の設定をshellで行う必要がある。
  - Ansibleを用いたmysqlモジュールについての情報が少ないように思える。


MySQLは冪等性が担保されているとのことなのですが、MySQLモジュールだけでは対応できない処理もあったりするのでで、これらのモジュールは適宜使い分けて使用するのが良さそうです。

### mysql_user
MySQLへのユーザーの追加、権限付与およびパスワード変更などのMySQLユーザーの管理を行うことができます。
主なパラメータ

- host = クエリを行う対象ホスト

- login_user = mysqlへログイン時のユーザ名

- login_host = mysqlへログイン時のホスト名

- login_password = mysqlへログイン時のパスワード

- login_port = ログイン時のポートを指定（デフォルトの3306以外を指定）

- name = 追加/削除するユーザー名

- priv = 権限の指定
※詳細は下記のおまけに記載しています。
　

- state = ユーザの存在要否
present = 存在しない場合は追加（デフォルト）
absent = 存在する場合は削除


### mysql_db
データベースの新規作成、使用する文字コードの設定などのデータベース管理を行う。
主なパラメータ

- login_user = mysqlへログイン時のユーザ名

- login_host = mysqlへログイン時のホスト名
 
- login_password = mysqlへログイン時のパスワード

- login_port = ログイン時のポートを指定（デフォルトの3306以外を指定）

- name = 操作対象のデータベース名

- state
present = 存在しない場合は追加（デフォルト）
absent = 存在する場合は削除
dump = 指定されたデータベースのバックアップを作成
import = SQLダンプファイルをデータベースにインポート


公式ドキュメント
https://docs.ansible.com/ansible/latest/collections/community/mysql/index.html

# まとめ
Ansibleでのデータベースの自動化は、処理の可視化が少し手間であり、ミスに気づくのが困難であるといった点や自動化した際に元データが改竄などされることを危惧し、安全性を考慮して開発環境や検証環境を構築する際のみ自動化。本番環境は手動で設定を行うというのが良いなぁと思いました〜。

簡単に処理を可視化できる方法などがあればぜひ教えてください〜
ありがとうございました〜


# おまけ
mysql_userモジュールのprivの権限の指定では「ALL;GRANT」で全権限を付与していることがほとんどだと思います。しかし、権限を付与する必要のないものについてはできるだけ付与するべきではないと思います。
そんな時に個別で権限を付与する方法があります。

以下の通りに、privパラメータにデータベース名と権限をそれぞれ指定します。

```
- name: test MySQL_user priv
  mysql_user:
    login_user: root
    login_password: "{{ user_password }}"
    login_host: "localhost"
    name: menta
    host: "localhost"
    password: "{{ user_password }}"
    state: present
    priv: "wordpress_db.*:SELECT,INSERT"
```
プレイブックの実行後、MySQLの権限設定を確認します。

```
[root@dev menta]# mysql -u root -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.40 MySQL Community Server - GPL

Copyright (c) 2000, 2024, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW GRANTS FOR menta@localhost;
+-----------------------------------------------------------------+
| Grants for menta@localhost                                      |
+-----------------------------------------------------------------+
| GRANT USAGE ON *.* TO `menta`@`localhost`                       |
| GRANT SELECT, INSERT ON `wordpress_db`.* TO `menta`@`localhost` |
+-----------------------------------------------------------------+
2 rows in set (0.00 sec)
```

mentaユーザーが対象ホストであるlocalhostに対して接続した際に、wordpress_dbにSELECT,INSERT権限を付与しているのが確認できました。

mysql_userモジュールはこういった個別の権限付与も行えるのでぜひ試してみてください！