【初心者向け】Rails6で作られたWebアプリをCircleCIを使いAWS ECR・ECSへ自動デプロイする方法②-1 インフラ構築編【コンテナデプロイ】

記事の続きをご覧いただきありがとうございます。
[前回の下準備編](https://qiita.com/Kiyo_Karl2/items/5f77d6f59bcddf05c614)の続きになります。今回はインフラ構築編②-1です。

| タイトル|
|:-----------|
| [① 下準備編](https://qiita.com/Kiyo_Karl2/items/5f77d6f59bcddf05c614)     | 
| [②-1 インフラ構築編](https://qiita.com/Kiyo_Karl2/items/ddf03ac97ab649b63c1d)  **←今ここ！**        | 
| ②-2 インフラ構築編(執筆中）         | 
| 自動デプロイ編(執筆中）      | 
少し長いので覚悟してください！笑

それでは、早速やってきましょう！

# インフラ構築編②-1
最初に流れを説明します。ここでやることは主に2つだけですが、色々と設定する項目があります。地道にやっていきましょう。

- クラスターの作成
- RDSの設置

このような構成になってます。

### クラスターの作成
クラスターの作成をawsコマンドを使って作成します。クラスターというのはコンテナインスタンスの集合体の名称です。
（クラスターという単語は、今年話題になったので日本語の意味からなんとなく察しが付いた方も多いと思います）

ざっくりいうと、このクラスターの中にRailsとNginxのDockerコンテナ（このDockerコンテナの集まりをServiceと呼びます）が配置されるといった感じです。

以下のコマンドを順番に実行して作成していきます。

```
$ ecs-cli configure profile --profile-name 任意のプロフィール名 --access-key アクセスキー --secret-key シークレットアクセスキー
$ ecs-cli configure --cluster 任意のクラスター名 --default-launch-type EC2 --config-name 任意の設定名 --region ap-northeast-1
$ ecs-cli up --keypair キーペア名 --capability-iam --size 2 --instance-type t2.small --cluster-config 任意の設定名 --ecs-profile 任意のプロフィール名
```

私の場合は、アプリ名(protuku-app)を名前にしたので、

```
$ ecs-cli configure profile --profile-name protuku-app --access-key xxxxxxxxxxxxxxxx --secret-key xxxxxxxxxxxxxx
$ ecs-cli configure --cluster protuku-app-cluster --default-launch-type EC2 --config-name protuku-app-cluster --region ap-northeast-1
$ ecs-cli up --keypair protuku-app --capability-iam --size 2 --instance-type t2.small --cluster-config protuku-app-cluster --ecs-profile protuku-app
```
のような感じでコマンドを実行しました。

また、私の場合、最後のecs-cli upコマンドを実行したとき

```
time="2020-10-22T20:41:46+09:00" level=fatal msg="Error executing 'up': describe instance type offerings: AuthFailure: AWS was not able to validate the provided access credentials\n\tstatus code: 401, request id: xxxxxxxxx
```
のようなエラーが出ました。もし、このようなエラーが起きたら、キーペアやアクセスキーの設定が間違っている可能性があります。私は、IAMの作成からやり直したらうまくいったのでこの辺の設定が間違っていた可能性があります。

また、ローカルのPCの時刻がずれていてもこのようなエラーが起きる可能性がありますので、PCの時刻がずれていないかどうか確認してください。
詳しくは[こちらの記事](https://qiita.com/iam_nk/items/7acdd5e67d4a5c9ce6e2)を参考にしてみるといいかもしれません。

最後のecs-cli upコマンドの実行に成功すると次のように、クラスター用のVPC、サブネット、セキュリティグループなどが作成されます！

```
$ ecs-cli up --keypair protuku-app --capability-iam --size 2 --instance-type t2.small --cluster-config protuku-app-cluster --ecs-profile protuku-app
INFO[0000] Saved ECS CLI cluster configuration protuku-app-cluster-4
INFO[0000] Using recommended Amazon Linux 2 AMI with ECS Agent 1.46.0 and Docker version 19.03.6-ce
INFO[0000] Created cluster                               cluster=protuku-app-cluster region=ap-northeast-1
INFO[0001] Waiting for your cluster resources to be created...
INFO[0001] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
INFO[0062] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
INFO[0122] Cloudformation stack status                   stackStatus=CREATE_IN_PROGRESS
VPC created: vpc-xxxxxxxxxxxxxxxxxx
Security Group created: sg-xxxxxxxxxxxxxxxxxx
Subnet created: subnet-xxxxxxxxxxxxxxxxxx
Subnet created: subnet-xxxxxxxxxxxxxxxxxx
Cluster creation succeeded.
```

ServicesからElastic Container Service(ECS)を選択し、Clusterをクリックすると、以下のようにクラスターが生成されているのが確認できると思います。（こちらはデプロイ後の画面なのでService、Taskが1になってますが、実際はまだ作成していないので0になっているはずです。）

![スクリーンショット 2020-11-16 154912.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/e7ce94e2-50b1-e0b9-7d69-3f7f7d184cd0.png)

## RDSの作成
次にRDSを作成していきます。DBサーバーにはMySQLを利用します。
RDSというのは、 AWSのフルマネージドなリレーショナルデータベースのサービスになります。バックアップ、DBのアップデート、スケーリングなどをAWSがすべて自動でやってくれるので、よりコアな開発に集中することができる！といったものです。

RDSにはインターネット上からアクセスできないようにしたいのでプライベートサブネットに配置します。また、冗長化のために複数のアベイラビリティゾーンにRDSを設置していきます。

まず、事前準備として、RDS用のプライベートサブネットを2つ（リージョンが1aと1cのものでいいと思います）と、DBパラメータグループ、DBオプショングループを作成していきます。

### RDS用のプライベートサブネットの作成
他記事で恐縮ですが、プライベートサブネットの作成に関しては[こちらの記事](https://qiita.com/hiroshik1985/items/9de2dd02c9c2f6911f3b)が大変わかりやすいので、こちらを見て作成してみてください。VPCはすでにあるのでサブネットの作成だけでOKです。
一番近い東京リージョンであるap-northeast-1aと1cのふたつのプライベートサブネットを作りこのサブネットにRDSを設置していきます。
### RDS用のサブネットグループを作成する
サブネットグループというのは、VPC内にあるサブネットを複数指定して、RDSインスタンスが起動するサブネットを指定した設定のことです。マルチAZを実現させるために、この設定をする必要があります。

まず、ServicesからRDSのコンソールへいき、Subnet groupsを選択し、Create DB Subnet Groupをクリックします。
以下のように任意の名前を入れます。VPCには作成したVPCを選択します。
![スクリーンショット 2020-11-16 162151.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/ebe7b025-ac9e-a524-51fd-d776a1aef539.png)

次に最初に作った2つのプライベートサブネットを追加していきます。
Avalilability Zonesは1aと1c選択し、作成したサブネットを2つ選択して、Createをクリックして作成完了です。
![スクリーンショット 2020-11-16 162416.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/238878ce-cced-34fc-7cd0-582e8aa38c47.png)




### DBパラメータグループの作成
RDSではDBの設定ファイルを直接編集するといったことができないので、代わりにパラメータグループというのを使って設定値を編集することができます。
デフォルトでパラメータグループは作成されるのですが、こちらは設定値を変えることができないので、自分で作成する必要があります。

RDSのコンソールからParameter groupsをクリックし、Create parameter groupをクリック
group familyにmysql5．7を選択し、任意の名前を入れてCreateして完了です。
![スクリーンショット 2020-11-16 235242.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/1124b98c-2064-24d0-8c10-144a93a7657b.png)



### DBオプショングループの作成
オプショングループはDBの機能的な部分を設定します。プラグインを導入したいとかそういったときに利用します。
こちらもデフォルトで設定されるのですが、デフォルトのものを編集するのではなく、自分で作成したものを編集するのがセオリーのようです。後々変更したいといったときのために作成しておきます。

RDSのコンソールからOption groupsを選択し、Create groupをクリック
こちらも任意の名前を入力して、mysqlの5.7を選択し、createをクリックして作成完了です。
![スクリーンショット 2020-11-17 001027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/72a0e51d-df04-a693-668a-255401e65518.png)

### RDSインスタンスの設置
さて、下準備が整ったのでやっとインスタンスを作成できます！
RDSのコンソールからDatabaseを選択し、Create databaseをクリック。
スタンダードを選択し、DBはMySQLを選択
![スクリーンショット 2020-11-16 155517.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/57aa9034-4d5c-36f0-d0a0-468b4e79e383.png)
今回は無料タイプを選択します。
![スクリーンショット 2020-11-16 155601.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/396a0c44-8bc2-2077-2c63-b2bbaa4fde3f.png)
次に、任意のDBインスタンス名を入力します。

Credentials Settingsをクリックし、DBに接続するときの任意のユーザー名とパスワードを設定します。
![db_name.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/b5091d6e-ff83-1748-304e-a32041b843cc.png)

こちらはなるべく安く済ませたいので、バースト可能クラスを選び、t3.microを選択します。
![スクリーンショット 2020-11-16 155920.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/19dde83c-80cf-8e91-5b81-e44ad6ca4278.png)
マルチAZの設定は今回は無しにします。作成すると自動でマルチAZにできるのですが、料金がかかってしまうため設定しません。デフォルトだと作成するにチェックが入っているので気を付けましょう。（英語版だけかも）
![スクリーンショット 2020-11-17 002910.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/596ff72d-f23c-9de2-9640-d98634574dab.png)
作成したVPCとサブネットグループを選択します。パブリックアクセスは無しを選択します。
![スクリーンショット 2020-11-17 002925.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/986ad3cc-a97d-ab45-9309-44c6371add4c.png)
ここで新規にRDSのセキュリティグループを作成します。任意の名前を入力し、アベイラビリティゾーンは1aを選択します。
ポート番号はデフォルトの3306のままいきます。
![スクリーンショット 2020-11-17 003027.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/b4cceaec-a8fa-488e-7b77-acad3c667e2b.png)
次に追加の接続設定を開き、database nameを入力します。
これは、Railsアプリの```config/database.yml```の```production:```にあるdatabaseの名前と同じ名前を入力しましょう。
たとえば私の場合は、webapp_productionと入力しました。
その後、上記で作成したパラメータグループとオプショングループを選択します。（画像は諸事情によりデフォルトのままになってますので気をつけてください。）
![スクリーンショット 2020-11-17 004248.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/37606569-e29f-00fa-a479-d666ffd29eda.png)

その他色々設定がありますが、他はデフォルトのままでとりあえずはOKだと思います！

設定があっていることを確認してCreateDatabaseをクリックしてRDSの作成は完了です。

### RDSのセキュリティグループを設定する
現状のままではセキュリティグループが設定されていないので、DBにすべてのトラフィックを許可してしまってる状態です。これではセキュリティー上よろしくないので、DBにはサーバーからのSSH接続のみ許可するように設定していきます。

EC2のコンソールへいき、Security Groupsを選択し、Edit inbound rulesを選択します。
![スクリーンショット 2020-11-17 214920.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/7c38c2bf-0b09-1285-48bf-b0d91095319d.png)
設定は

- タイプ: MYSQL/Aurora
- プロトコル: SSH
- ポート: 3306
- ソース: クラスターのセキュリティグループ（最初にawsコマンドを実行したとき自動で作られてるはずです）

設定を入力したら、Createをクリックします。これでセキュリティグループの作成は完了です。
![スクリーンショット 2020-11-17 215127.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/e872d03a-1bc2-c85a-178c-eeebf11dbadf.png)
セキュリティグループの作成が完了したら、実際にDBに接続できるか確認してみましょう。
サーバーにSSHログインして、以下のコマンドを実行します。サーバーへのSSHログインの方法は割愛します。
windowsならRLoginやPuttyなどを使ってログインできるのでググってみてください。

```
[ec2-user@ip-xxxxxxxx ~]$ mysql -u 設定したユーザー名 -h RDSのエンドポイント -p
```
以下のような画面になったら成功です。（mysql not found とかでてきたらmysqlをインストールする必要があります。ref: https://hacknote.jp/archives/51267/)
![スクリーンショット 2020-11-17 215459.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/632678/af980a60-a1b2-db24-c752-7e9a4dde3b10.png)

# 最後まで読んでいただきありがとうございます！
今回はここで一旦区切ります。次回はインフラ構築編②-2として、Webからのアクセスを負荷分散するために、ALB（アプリケーションロードバランサー）を作成する方法を書いていこうと思いますので、乞うご期待ください！

思い出しながら調べつつ記事を書いているので、ご指摘や、ご不明な点などあればコメントいただけますと嬉しいです！