Terraformを使ってMariadbを操作する

# 初めに
最近MariaDBを使って個人の開発を行っています。
いつも通りMariaDBの操作をしている際にTerraformで管理できたら便利だと考え、調べてみると下記のmysqlプロバイダが存在していたので、使ってみました。

https://www.terraform.io/docs/providers/mysql/index.html

# 雑にMariaDBを構築する
今回はdocker-composeを使ってmariadbを立てました。

```yaml:docker-compose.yaml
version: '3.7'
services:
  db:
    image: mariadb:10.5.10
    restart: always
    ports:
      - 3306:3306
    environment:
      - MARIADB_ROOT_PASSWORD=root
```

`docker-compose.yaml`が作成できたので下記コマンドで立ち上げます。

```
$ docker-compose up -d
```

# TerraformでMariadbを扱えるようにする

利用しているTerraformのバージョンは下記です。

```bash
$ terraform version
Terraform v0.12.31
```

ちなみに1.0.0と1.4.0でmysqlのプロバイダが使えるか試してみましたができませんでした。
`main.tf`を作成した後、下記のように表記します。

```terraform:main.tf
provider "mysql" {
  endpoint = "127.0.0.1:3306"
  username = "root"
  password = "root"
}
```

最後に下記コマンドを入力して準備完了です。

```bash
$ terraform init
```


# データベースを作成する
ここではtestdbという名前でデータベースを作成します。

最初にDBが作成されていないことを確認します。

```bash
$ mysql -h 127.0.0.1 -u root -p
Enter password: root

mysql> show databases;
--------------
show databases
--------------

+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
+--------------------+
3 rows in set (0.00 sec)
```


## Terraformでデータベースを作成する
先ほど作成したmain.tfに下記を追記します。

```terraform:main.tf
resource "mysql_database" "testdb" {
  name = "testdb"
}
```

`terraform apply`してDBに反映します。

```bash
$ terraform apply 
terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # mysql_database.testdb will be created
  + resource "mysql_database" "testdb" {
      + default_character_set = "utf8"
      + default_collation     = "utf8_general_ci"
      + id                    = (known after apply)
      + name                  = "testdb"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: 
```

`Enter a value:`にyesと入力して反映させた後、DBを確認します。
`testdb`が作成されるのを確認できました。

```bash
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| testdb             |
+--------------------+
4 rows in set (0.00 sec)
```

# TerraformでDBのユーザを作成する

Terraformでデータベースを作成しました。
次に、ユーザを作成します。

```terraform:main.tf
resource "mysql_user" "testuser" {
  user               = "testuser"
  host               = "%"
  plaintext_password = "testuser"
}
```

applyして確認してみます。

```bash
mysql> select user, host from mysql.user;
+-------------+-----------+
| User        | Host      |
+-------------+-----------+
| root        | %         |
| testuser    | %         |
| mariadb.sys | localhost |
| root        | localhost |
+-------------+-----------+

$ mysql -h 127.0.0.1 -u testuser -p
Enter password: testuser

mysql>
```


## 作成したユーザに権限を付与する

先ほどユーザを作成したので、テーブルを作成する権限を付与します。
ちなみに作成したばかりなので権限は何もないです。

```bash
show grants for `testuser`@`%`;
+---------------------------------------------------------------------------------------------------------+
| Grants for testuser@%                                                                                   |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `testuser`@`%` IDENTIFIED BY PASSWORD '*3A2EB9C80F7239A4DE3933AE266DB76A7846BCB8' |
+---------------------------------------------------------------------------------------------------------+
```

`main.tf`に下記を追加してapplyを行います。

```terraform:main.tf
resource "mysql_grant" "testgrant" {
  user       = mysql_user.testuser.user
  host       = mysql_user.testuser.host
  database   = mysql_database.testdb.name
  privileges = ["CREATE"]
}
```

applyしたら確認を行います。testdbに対してCREATEの権限が付与され問題なさそうです。

```bash
show grants for `testuser`@`%`;
+---------------------------------------------------------------------------------------------------------+
| Grants for testuser@%                                                                                   |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `testuser`@`%` IDENTIFIED BY PASSWORD '*3A2EB9C80F7239A4DE3933AE266DB76A7846BCB8' |
| GRANT CREATE ON `testdb`.* TO `testuser`@`%`                                                            |
+---------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
```


# Terraformでgrantを変更する
先ほどgrantで権限の付与を行いました。次にCREATEに加えDELETEを付与してみます。

```terraform:main.tf
resource "mysql_grant" "testgrant" {
  user       = mysql_user.testuser.user
  host       = mysql_user.testuser.host
  database   = mysql_database.testdb.name
  privileges = ["CREATE","DELETE"]
}

```

コードを変更したらapplyして変更してみます。変更内容は下記のようになりました。
特に問題なく変更できていそうです。

```bash
# mysql_grant.testgrant must be replaced
-/+ resource "mysql_grant" "testgrant" {
        database   = "testdb"
        grant      = false
        host       = "%"
      ~ id         = "testuser@%:`testdb`" -> (known after apply)
      ~ privileges = [ # forces replacement
            "CREATE",
          + "DELETE",
        ]
        table      = "*"
        tls_option = "NONE"
        user       = "testuser"
    }

mysql> show grants for `testuser`@`%`;
+---------------------------------------------------------------------------------------------------------+
| Grants for testuser@%                                                                                   |
+---------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO `testuser`@`%` IDENTIFIED BY PASSWORD '*3A2EB9C80F7239A4DE3933AE266DB76A7846BCB8' |
| GRANT DELETE, CREATE ON `testdb`.* TO `testuser`@`%`                                                    |
+---------------------------------------------------------------------------------------------------------+
2 rows in set (0.00 sec)
```

# 最後に
TerraformでMariaDBを操作してみました。tableの作成や、データのinsert、selectなどは行うことができないようで、あくまでも初期構築やユーザの管理などがメインなようです。勝手な想像ですがテーブルの作成はマイグレーションツール?などで管理するもの考えられたのかなーなんて思ってました。
たくさんのインフラリソースをTerraformで管理することがで、他にもdockerなどもTerraformで管理できるようなので使ってみたいですね。
ありがとうございました。

# 補足

今回はmysqlのプロバイダを利用しましたがgithubを見ると、現在はメンテナンスがされておらず新しいバージョンも出ていないようです。

- https://www.terraform.io/docs/providers/mysql/index.html


# 参考
- https://github.com/hashicorp/terraform-provider-mysql
- https://www.terraform.io/docs/providers/mysql/index.html



# main.tfの全体のコード

```terraform:main.tf
provider "mysql" {
  endpoint = "127.0.0.1:3306"
  username = "root"
  password = "root"
}


resource "mysql_database" "testdb" {
  name = "testdb"
}


resource "mysql_user" "testuser" {
  user               = "testuser"
  host               = "%"
  plaintext_password = "testuser"
}


resource "mysql_grant" "testgrant" {
  user       = mysql_user.testuser.user
  host       = mysql_user.testuser.host
  database   = mysql_database.testdb.name
  privileges = ["CREATE","DELETE"]
}
```