VagrantにMySQLをインストールし、ローカルから接続する

#この記事について
テスト用のDBが欲しかったのですが、ローカル環境にDBを作成したくなかったので、Vagrantを立てて、そこにMySQLを落としてみました。そのやり方を記述します。また、ローカル側のMySQLWorkbenchからVagrant上のMySQLに接続する際にエラーが出たのですが、グーグルで調べても解決策の情報があまり載っていなかったため、苦労しました。そこも触れていきます。

##環境
<b>ローカル</b>
Mac
Vagrant 2.2.6
Virtualbox 5.2

<b>仮想環境 (192.168.33.10)</b>
CentOS 7.2

##手順
以下の流れで行なっていきます。
1. Vagrantfileを作成する(vagrant init)
2. Vagrantfileとprovision.shを編集する
3. Vagrant upする
4. MySQLに接続してみる
5. MySQLへの接続許可するように設定する

##TRY!
###1. Vagrantfileを作成する(vagrant init)
まず、Mac上で仮想サーバーを立てるフォルダを作成し、`vagrant init`のコマンドを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/d2f577ca-6881-1c76-b704-9c7e71c540b4.png)

これで、Vagrantのテンプレファイルが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/cad7e374-4d10-7bd1-5368-da880510bcf5.png)

###2. Vagrantfileとprovision.shを編集する
次に、Vagrantfileを編集します。ちなみにVagrantileとは、`仮想サーバーを立てる際に、どうやってサーバーを立てるかの指示が書かれているもの`で、例えば、どんなOSを仮想サーバーに入れるのか、フォルダの書込許可はどのユーザーに当てるのか、などが設定できます。

今回は、Vagrantfileで3つの指示を指定します。
1. CentOSをOSに指定
2. MySQLをインストール
3. ローカル（ホスト）からアクセスできるIPアドレスを解放

2については、サーバーを立てた後でCentOSのコマンドを叩いても可能ですが、サーバーを立てる際にインストールした方が手間が省けます。

####1. CentOSをOSに指定
Vagrantfileをテキストエディタで開き、以下の箇所を変更します。

```bash
  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://vagrantcloud.com/search.
  config.vm.box = "base"
```

After:

```bash
  # Every Vagrant development environment requires a box. You can search for
  # boxes at https://vagrantcloud.com/search.
  config.vm.box = "bento/centos-7.2"
```

見ての通り、`config.vm.box`ではOSを指定することができるのがわかるかと思います。

####2. MySQLをインストール
次に、MySQLをインストールするため、先ほどのコードの下に、以下を追記します。

```shell
  #Run provision.sh
  config.vm.provision :shell, :path => "provision.sh"
```
`config.vm.provision :shell`は`.sh`ファイルを実行するという指示を意味します。`:path => `の後に`.sh`ファイルのパスを書きます。今回は`provision.sh`というファイルを指定します。

次に、`provision.sh`を作成しましょう。ターミナルで`vi provision.sh`を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/1cbe4d4a-efbd-9001-1339-cda283333fd1.png)

作成された`provision.sh`で以下のようにMySQLをインストールし、デーモンを起動するようにします。

```shell
# Install MySQL
sudo yum -y install http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
sudo yum -y install mysql-community-server

# Start MySQL when vagrant is up
sudo systemctl enable mysqld.service
sudo systemctl start mysqld.service
```

####3. ローカル（ホスト）からアクセスできるIPアドレスを解放
最後に、ローカル（ホスト）から仮想サーバー（ゲスト）アクセスできるIPアドレスを解放するため、Vagrantfileの`config.vm.network "private_network"`の箇所をコメントアウトします。

```shell
  # Create a private network, which allows host-only access to the machine
  # using a specific IP.
  config.vm.network "private_network", ip: "192.168.33.10"
```

これにより、Vagrantを起動するだけで、`192.168.33.10`にMySQLの入ったCentOSが作成されます。

##3. Vagrant upする
次に、Vagrantを起動するため、`vagrant up`を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/0d3de10c-979d-4bf9-0711-0e4df181d0f1.png)
こんな感じで、仮想サーバーが作られていきます。

##4. MySQLに接続してみる
このままMySQLに接続するとどうなるのかを検証します。
まず、仮想サーバー（ゲスト）にSSHでアクセスし、MySQLに接続できるか確認します。仮想サーバー（ゲスト）にSSHでアクセスするため、以下のコマンドを叩きます。

```shell
$vagrant ssh
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/d9e9e758-8f53-785c-dbcb-bfd620b926a7.png)
これで、Vagrant内に入れました。

次に、MySQLに接続します。`provision.sh`で作成されたMySQLでは、デフォルトではパスワードのないrootユーザーが作成されているので、以下のコマンドで接続できます。

```shell
$mysql -u root -p
```
すると、パスワードを聞かれますが、Enterを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/04c82f00-b2fd-0f85-751f-9de16ff9393a.png)

これで、MySQLへの接続が確認できました。

今度は、ローカル（ホスト）からMySQLに接続ができるか確認するため、MySQLWorkbenchを開き、以下の情報を入力します。

Hostname: 192.168.33.10
Port: 3306
Username: root
Password: (blank)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/e6ed5b2c-2490-ee78-8c4a-09114aae0dc9.png)

すると、以下のようなメッセージが出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/2d4f83c8-8911-2476-01be-f6dadfa073f8.png)
`Can't connect to MySQL server on '192.168.33.10' (60)`

同じことがMacのターミナルからtelnetで確認できます。

```shell
$telnet 192.168.33.10 3306
```
実際のスクショ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/a5d51812-8468-6b91-84af-3d1596af91b5.png)

どうやら、`192.168.33.10`自体に繋がってなさそうです。
`ping`で接続確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/c47f629c-3978-35c4-70f5-cddc8a5989e3.png)
`ping`すら通っていませんね。。

`Vagrantfile`のあるフォルダ配下で、`vagrant reload`を実行し、再度`ping`してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/749096ab-703d-e606-8767-7e13e098ecb7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/c1b20f41-a15c-c191-f17e-f9b32817df80.png)

`ping`が通りました。自分の場合、`config.vm.network "private_network"`のコメントアウトをしたのが実は`vagrant up`の後だったのでこのエラーが出ていたようです。記事を書きながら動かしていたのでうっかりしていました。

再度、ローカルからMySQLに接続できるか確認します。今回はTelnetのみ実行します。MySQLWorkbenchでも同じ結果が出ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/d4001a70-2b1f-7671-4e6f-b2e03a6ff840.png)

これは、仮想サーバ（ゲスト）側のMySQLが、ローカル（ホスト）からのアクセスを拒んでいる時に出てくるメッセージです。次のステップでこれを解消します。

###5. MySQLへの接続許可するように設定する
再度、仮想サーバー（ゲスト）にSSHでアクセスし、MySQLに`root`ユーザーでアクセスします。次に、以下のクエリを実行すると仮想サーバー（ゲスト）のMySQLはどこからでも`root`ユーザーのアクセスを許可するようになります。

```sql
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
```

実際のスクショ：
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/7ec8db35-3b91-1399-8439-d0eeb332b9e5.png)

実行後`Ctrl+C`で`mysql>`を閉じ、`systemctl restart mysqld`でデーモンを再起動します。この時、VagrantのRootユーザのパスワードが聞かれます。パスワードはディフォルトで`vagrant`です。

ローカル（ホスト）側に戻り、MySQLWorkbenchで接続確認します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/464595/f09b29b4-7af0-e470-792f-b0f4ecf9d26e.png)

無事接続できました。

##最後に
以上、VagrantにMySQLをインストールし、ローカルから接続する方法でした。自分はあまり環境構築に慣れていないため、苦労しました。。どうか参考になったと感じたら「いいね」してもらえると幸いです。

##参考
[Connect to a MySQL Server inside of a Vagrant Machine from the Host Machine](https://qiita.com/captain-goblin/items/a64bee244dcf86d563da)
[vagrant上のmariadbにローカルのマネージメントツールからアクセスするためにやったこと](
https://blog.42mate.com/connect-to-a-mysql-server-inside-of-a-vagrant-machine-from-the-host-machine/)