AWS FargateにRailsアプリケーションをデプロイする手順

[AWS Fargate](https://aws.amazon.com/jp/fargate/?whats-new-cards.sort-by=item.additionalFields.postDateTime&whats-new-cards.sort-order=desc&fargate-blogs.sort-by=item.additionalFields.createdDate&fargate-blogs.sort-order=desc)について無知だったので、RailsアプリケーションをFargateで動かすことを目指して、色々触っていました。

とりあえず、RailsアプリをGithubActionsで自動デプロイして[Sidekiq](https://github.com/mperham/sidekiq)も裏で動く、みたいなところまでできるようになりましたので、その手順を半年後の自分でもわかるように残しておきます。

※本番環境で使われるベストプラクティスを示しているとかではありません。ご了承ください :pray:


## AWSコンソールでの設定

東京リージョンを選択しておきます。
![AWS_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/c3ba367e-8f31-a6f4-82f5-9bd6874ad2b5.png)

### IAMポリシー・IAMロールの作成
ECSを動かす際に必要なIAMポリシー作成とIAMロールの編集を行います。


まずは、以下から、IAMポリシーの作成を行います。
![IAM_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/08b3e523-289a-9e44-642d-bc7a156e56ed.png)

ポシリーの作成画面に遷移後、JSONのタブを開きます。
![スクリーンショット 2023-03-15 21.39.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/4df3b3c7-fd48-261e-efa8-aa4e3c7cda30.png)

こちらのJSONを入力ください。自分のアカウントIDを入力する欄もあります。アカウントIDの確認は次に示します。

```json
{
    "Statement": [
        {
            "Action": [
                "ecr:GetAuthorizationToken",
                "ecr:BatchCheckLayerAvailability",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Effect": "Allow",
            "Resource": "*",
            "Sid": ""
        },
        {
            "Action": [
                "ssmmessages:OpenDataChannel",
                "ssmmessages:OpenControlChannel",
                "ssmmessages:CreateDataChannel",
                "ssmmessages:CreateControlChannel",
                "ssm:GetParameters",
                "kms:Decrypt"
            ],
            "Effect": "Allow",
            "Resource": "*",
            "Sid": ""
        },
        {
            "Action": "iam:PassRole",
            "Effect": "Allow",
            "Resource": "arn:aws:iam::###:role/ecsTaskExecutionRole", //自分のアカウントIDを###に入力します
            "Sid": ""
        },
        {
            "Action": "ecs:ExecuteCommand",
            "Effect": "Allow",
            "Resource": "arn:aws:iam::###:role/ecsTaskExecutionRole", //自分のアカウントIDを###に入力します
            "Sid": ""
        }
    ],
    "Version": "2012-10-17"
}
```


#### アカウントIDの確認方法

AWS管理コンソールの右上をクリックします。
すると、アカウントIDが載っています。こちらは`1234-56798-9123`のようにハイフン込みで記載がありますが、上記のIAMポリシーのJSONにはハイフンなしで記載してください。
![AWS_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/60df0f74-93ca-02ef-eda0-102e5bc7576c.png)

例)ハイフンなしの例
```json
"Resource": "arn:aws:iam::123456789123:role/ecsTaskExecutionRole",
```

IAMポリシーのJSONの入力が完了したら次へ進み、IAMポリシーの作成まで進んでください。
名前は「ecs-task-execution-policy」としています。

![IAM_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/44f395e0-bbb6-bf96-fe77-c0840553e085.png)

IAMポリシーの作成が完了したら、次は、IAMロールの作成を行います。



### IAMロールの編集

IAMロールから「ecsTaskExecutionRole」と検索して、次へ進みます。

![IAM_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/53a16910-05df-d845-edfc-9602e00c7635.png)

続いて、「許可を追加」から「ポリシーをアタッチ」へ進みます。

![IAM_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/9e315943-f92f-de20-598d-c6ea5943977d.png)


先ほど作ったポリシー「ecs-task-execution-policy」で検索して、チェック後、許可を追加します。
![IAM_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/62331333-c030-2c7c-5e0a-1c7849e7de17.png)

これでIAMの編集は以上です。


### ECRの作成
DockerHubのようなもので、コンテナイメージを保存してしておくことができます。
あとの章で、Railsを動かすためのDockerfileの作成を行います。

以下からリポジトリを作成を行います。

![Amazon_ECR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/5fc35454-0fdb-2eed-d6ca-c51d43e53b72.png)

作成画面へ行ったら以下のように入力していきます。

|  フォーム  |  値  |
| ---- | ---- |
|可視設定|プライベート|
|リポジトリ名|fargate-test|
|プッシュ時のスキャン|チェックを入れる|

![Amazon_ECR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/e9a17105-3fc4-5750-faff-b9ba0d3babb0.png)
![Amazon_ECR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/c865ae75-42f2-28b0-fc82-297bf01afa76.png)

上記の設定でリポジトリを作成します。
ここで表示されているリポジトリ名をECS Taskの作成の章で利用します。


### ECS Taskの作成

`※左上の「新しいECSエクスペリエンス」をオフにしていただくと、以下のスクショと似た画面になると思います。`

docker-compose.ymlのようなもので、どのコンテナを動かすかなどの設定を記載していきます。
こちらから「新しいタスク定義の作成」を行います。
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/247e527e-36ca-8995-3722-5962c1a3532f.png)

起動タイプは「Fargate」を選択
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/a644f7a4-2c8c-7b7b-8b94-fdff79ef154a.png)

タスク定義を入力していきます。

|  フォーム  |  値  |
| ---- | ---- |
|起動タイプ|Fargate|
|タスク定義名|fargate-test|
|タスクロール|ecsTaskExecutionRole|
|タスク実行ロール|ecsTaskExecutionRole|
|タスクメモリ(GB)|0.5|
|タスクCPU|0.25 vCPU|

イメージ
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/2335c37b-6a06-9291-b821-6febdc2ab853.png)
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/229c3718-7103-d3ad-049d-0e3b43b9ac12.png)

以下のボタンからコンテナの追加も行います。

![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/42bbf943-b4fa-ab5d-dc2d-ab4805ccb852.png)

入力内容は以下です。

|  フォーム  |  値  |
| ---- | ---- |
|コンテナ名|fargate-test|
|イメージ|#####.dkr.ecr.ap-northeast-1.amazonaws.com/fargate-test:latest(ECRを作成していたときのリポジトリ名が入ります) |
|ポートマッピング|80|
|環境のコマンド欄|/app/entrypoint.sh|

イメージ

![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/5f6cb591-149e-effd-f3e9-28c5c10cfd63.png)
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/0fd5d38e-79f7-0306-18ac-ffeaa8a52736.png)

こちらの入力ができたら、「作成」ボタンを押してタスクの作成を行います。
次にクラスターの作成を行います


### クラスターの作成
クラスターを作成します。このタイミングで同時にVPC,Subnetなども作成していきます。

1. クラスターテンプレートは、今回Fargateを利用するので「ネットワーキングのみ」を選択します。
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/82473b44-67cf-6742-49cf-cbb82e755f42.png)

2. クラスターの設定に進みます

|  フォーム  |  値  |
| ---- | ---- |
|クラスター名|fargate-test|
|VPCの作成|チェックする |
|CIDRブロック|10.0.0.0/16|
|サブネット1|10.0.0.0/24|
|サブネット2|10.0.1.0/24|
|CloudWatch Container Insights|チェックする|

![Amazon_ECS-2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/4851717a-1d21-023a-480d-7ac9192e8353.png)
![Amazon_ECS-3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/99e19843-6993-d4a4-4c31-2f13ed0d32e4.png)

上記の設定を入力したら、作成ボタンを押して作成を行います。

作成が完了したら以下のような画面になります。

![Amazon_ECS-4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/c691056c-a1e5-8e0b-1c2a-fa1e852d1cca.png)


※ それぞれのVPC, サブネット, 　インターネットゲートウェイ, ルートテーブルに「fargate-test」のような名前をつけておくのがおすすめです。

例えばインターネットゲートウェイの名前が空ならば、タグ管理から
キー：Name
値：fargate-test
のようにして保存をします。

![VPC_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/f5aa9105-6722-ce15-a336-9af673330566.png)


すると、以下のようにNameタグが追加されます。

![VPC_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/9ca66ddf-cb01-e006-3de5-48e6ce256619.png)


### ロードバランサーの作成

EC2の画面からロードバランサーの作成が可能です。

![EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/dc3c093c-b980-738c-7580-a77dafa00dd7.png)

入力内容は以下になります。

|  フォーム  |  値  |
| ---- | ---- |
|ロードバランサーの種類|Application Load Balancer|
|名前|fargate-test|
|スキーマ|インターネット向け|
|ロードバランサーのプロトコル|HTTP|
|ロードバランサーのポート|80|
|VPC|クラスタ作成時に一緒に作成したVPC|
|アベイラビリティーゾーン|ap-northeast-1a, ap-northeast-1c両方にチェック|

イメージ
![ロードバランサーの作成___EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/f7b9fb93-e2d8-f57d-de43-b95ec7a02497.png)
![ロードバランサーの作成___EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/299c1b8e-759d-921a-9ad8-47338fb27c55.png)

※SSL証明書を取得後に、HTTPSプロトコルの追加は行います。

#### ロードバランサーのセキュリティグループ

続いて、セキュリティグループの設定を行います。

|  フォーム  |  値  |
| ---- | ---- |
|セキュリティグループの割り当て|新しいセキュリティグループを作成する|
|セキュリティグループ名|fargate-test|
|タイプ|HTTP|
|ソース|0.0.0.0/0, ::/0|

![ロードバランサーの作成___EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/49122380-2717-0e88-b874-8a09922983b9.png)

#### ロードバランサーのルーティング設定

続いて、ルーティングの設定を行います。

|  フォーム  |  値  |
| ---- | ---- |
|ターゲットグループ|新しいターゲットグループ|
|名前|fargate-test|
|ターゲットの種類|IP|
|プロトコル|HTTP|
|ポート|80|
|プロトコルバージョン|HTTP1|
|ヘルスチェックプロトコル|HTTP|
|ヘルスチェックパス|/api/health_check|

![ロードバランサーの作成___EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/6399f362-b780-1b5a-c6b5-f982d92bb7f1.png)

続いて、ターゲットの登録へ進みます。

|  フォーム  |  値  |
| ---- | ---- |
|ネットワーク|クラスタ作成時に一緒に作成したVPC|
|ポート|80|
|IP|ここでは空で大丈夫です|

![ロードバランサーの作成___EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/2272b8c5-9046-47d3-34d9-8de2187265e5.png)

こちらの設定を入力したら、確認後、作成を行います。


### サービスの作成

ECSクラスターの画面からサービスの作成が可能です。

![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/66f08401-626f-46ea-572c-0ccb550cfda2.png)

入力内容は以下になります。

|  フォーム  |  値  |
| ---- | ---- |
|起動タイプ|Fargate|
|クラスタ|fargate-test|
|サービス名|fargate-test|
|タスク定義|fargate-test|
|タスクの数|1|
|デプロイメントタイプ|Blue/Greenデプロイメント|
|デプロイメント設定|CodeDeployDefault.ECSAllAtOnce|
|CodeDeploy のサービスロール|AWSCodeDeployRole|

イメージ
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/a4000102-23e8-8082-73f3-a50a06ec4163.png)

次のステップに進みます。

|  フォーム  |  値  |
| ---- | ---- |
|VPC|クラスタ作成時に一緒に作成したVPCを選択|
|サブネット|クラスタ作成時に一緒に作成した2つのサブネットを選択|
|セキュリティグループ|fargate-test(ロードバランサー作成時に作成したセキュリティグループ|
|ロードバランサーの種類|Application Load Balancer|
|ヘルスチェックの猶予期間|300|
|ロードバランサー名|fargate-test(上で作成したロードバランサーを選択)|
|プロダクションリスナーポート|80:HTTP|
|テストリスナー|チェックなし|
|ターゲットグループ 1 の名前|fargate-test(ロードバランサー作成時に作成したものを選択)|
|ターゲットグループ 2 の名前|新規作成(ターゲットグループ1と異なる必要があるため)|
|ターゲットグループ 2 のプロトコル|HTTP|
|ターゲットグループ 2 のヘルスチェックパス|/api/health_check|
|サービスの検出の統合の有効化|チェックなし|

イメージ
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/7deb94b6-e6c7-037d-ddf4-648390b17cac.png)
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/1d89c7c8-2b50-6d40-d39e-21fea74ed6aa.png)

![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/67af044c-a2b1-de75-3a93-9f50f4ee9a38.png)

![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/2442e9c6-9a7c-d1bf-936a-8631cf93c52d.png)

![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/a52f7d02-8484-8e68-4de7-682570b90a9a.png)


ここまで入力したら次のステップへ進みます。

|  フォーム  |  値  |
| ---- | ---- |
|Service Auto Scaling|サービスの必要数を直接調整しない|

![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/b2e14a02-92be-5435-f30a-0521ded145cd.png)

次のステップへ進みます。
おそらくこれで確認画面が表示されます。問題なければ、サービスの作成を行います。

うまくいくと、以下のような作成完了画面になります。
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/4376bb12-e9a4-3d1b-6923-311788a7e4e0.png)

これでサービス作成は完了です。


### RDSの作成
MySQLの例で作成していきます。

が、まずはRDSの作成に必要なPrivateサブネットを2つ、それらをまとめたサブネットグループの作成を行います。
#### Private Subnetの作成
VPCの管理画面からサブネットの作成が可能です。
![サブネット___VPC_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/ade9cc01-dbae-6e81-c1d1-679b69fe59ef.png)


以下の内容で2つのSubnetを作成します。

| | VPC ID|  サブネット名  |アベイラビリティーゾーン|IPv4 CIDR ブロック|
| ---- | ---- | ---- | ---- | ---- |
|1|fargate-test|ffargate-test/Private-1a|ap-northeast-1a|10.0.2.0/24|
|2|fargate-test|ffargate-test/Private-1c|ap-northeast-1c|10.0.3.0/24|

イメージ
![VPC_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/425d0e4a-52e2-d383-b095-7ff17d10924b.png)

完成すると↓
![サブネット___VPC_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/2e8acaeb-8676-dc5a-db3f-f5b17bd25a36.png)


#### Subnet Groupの作成
RDS用に上で手順で作成した2つのPrivate SubnetをまとめるSubnet Groupを作成します。
ここから作成が可能です。

![RDS_·_AWS_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/d379964c-d411-4be8-a019-38a62f378747.png)

入力する値は以下になります。

|  フォーム  |  値  |
| ---- | ---- |
|名前|fargate-test|
|VPC|fargate-test|
|説明|fargate-test subnet group|
|アベイラビリティーゾーン|ap-northeast-1a, ap-northeast-1c|
|サブネット|10.0.2.0/24, 10.0.3.0/24|

イメージ

![RDS_·_AWS_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/b82450f2-5a9b-db27-5556-ffa6223dc708.png)

![RDS_·_AWS_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/924f080a-4ce3-d4e5-bd53-6cec841899e3.png)

こちらの設定を入力したら、作成を実行します。

#### RDSの作成
さてRDS作成の準備が以上で整いましたので、RDSの作成を行っていきます。
なお本記事ではMySQLを例にしています。

以下のボタンから「データベースの作成」を行います。
![RDS_·_AWS_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/5509f217-5d1e-34dc-ec67-6deaa4dc70e8.png)

作成画面に遷移したら、以下の内容を入力します。
今回はテンプレート「無料利用枠」で行います。

|  フォーム  |  値  |
| ---- | ---- |
|エンジンのタイプ|MySQL|
|DBインスタンス識別子|fargate-test|
|マスターユーザー名|admin|
|パスワード|ご自身で適当に|
|Virtual Private Cloud (VPC)|fargate-test(作成したVPC)|
|サブネットグループ|fargate-test(先程作成したSubnetGroup)|
|パブリックアクセス可能|なし|
|VPC セキュリティグループ|新規作成|
|新しい VPC セキュリティグループ名|fargate-test-rds|
|アベイラビリティーゾーン|指定なし|
|データベース認証|パスワード認証|

![Notification_Center.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/214e8e1d-9cf3-1e92-70e5-5434719e3ca8.png)

![RDS_·_AWS_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/d51acedb-347e-2705-4975-db2aa999ce05.png)

さらに以下の「追加設定」のボタンからデータベース名の入力も行います。

![RDS_·_AWS_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/e5c0228a-dff3-c784-a470-8e80584838a6.png)

上記の設定が完了したら、「データベースの作成」を行います。
データベース作成後は、 **パスワードの確認ができなくなります** ので、メモしておいてください。

### RDS用セキュリティグループの編集
先程RDSを作成したタイミングで一緒に作成されたセキュリティグループを編集していきます。
このセキュリティグループの編集によって、PrivateSubnetにあるRDSへの接続が可能になります。

先程作成されたセキュリティグループの「インバウンドルールを編集」から編集を行っていきます。

![EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/a2fe23ad-9e19-9c47-1c35-a0ddf180599b.png)

以下のようにルールの追加を行います。

|  フォーム  |  値  |
| ---- | ---- |
|タイプ|MYSQL/Aurorra|
|ソース|fargate-test|

![EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/50710444-54b9-8a58-3944-665406ce412b.png)

こちらの入力が完了したら、ルールを保存し完了です。


### System Managerでパラメータストアの作成
DBのパスワードなどの秘匿情報はコード上に残したくないので、ここに登録しておきます。

このページへ遷移して、、、
![AWS_Systems_Manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/2c296d1e-9172-0b37-df35-e48622be0723.png)

「パラメータの作成」を押します。
![AWS_Systems_Manager_-_Parameter_Store.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/2588e3c6-89b3-307d-b4a2-ed54c40193ae.png)


フォームが表示されます。

![AWS_Systems_Manager_-_Parameter_Store.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/16b02a59-52f0-61b3-a717-026a92ab1fd0.png)

4つのパラメータを入力します。
それぞれフォームには以下のように入力していきます。

|名前|タイプ|KMS キーソース|KMS キー ID|値|
| ---- | ---- |---| ---- | ---- |
|/fargate-test/rails-master-key|安全な文字列|現在のアカウント|alias/aws/ssm|Railsの config/master.key にある値を入力 |
|/fargate-test/db-username|安全な文字列|現在のアカウント|alias/aws/ssm|admin(RDS作成時に設定したユーザー名)|
|/fargate-test/db-password|安全な文字列|現在のアカウント|alias/aws/ssm|RDS作成時に設定したパスワード|
|/fargate-test/db-host|安全な文字列|現在のアカウント|alias/aws/ssm|先程作成したRDSのエンドポイントを入力|

RDSのエンドポイントは、ここを確認します。
![RDS_·_AWS_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/9e87c76e-3427-b4b5-23ae-981ab11e06a3.png)

パラメータストアの入力イメージ
![AWS_Systems_Manager_-_Parameter_Store.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/16f605b9-3cd0-977a-b286-16ca5ba36531.png)
![AWS_Systems_Manager_-_Parameter_Store.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/1b817219-4d2f-c985-fa92-bf768b850387.png)

4つの登録したらパラメータストアの入力は完了です。

### タスク定義で新しいリビジョンを作成

次に、先程作成したタスク定義で、今作ったパラメータストアの値を参照できるようにします。

タスク定義のページから「新しいリビジョンの作成」を行います
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/139fa898-db44-53db-e0cc-00e9ef022969.png)


以下のコンテナを押してコンテナの編集を行います。

![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/d5600ba0-460b-e896-37ca-9b81884ed447.png)

環境変数の欄に、上で作ったパラメータストア4つを参照できるように入力していきます。

さらに、Railsを起動するのに必要な環境変数も追加しておきます。こちらは秘匿情報ではないので、パラメータストアは利用していません。

全部で環境変数は以下の7つになります。

|  キー  |  Value| 値 |
| ---- | ---- | ---- |
|RAILS_ENV|Value|production|
|RAILS_SERVE_STATIC_FILES|Value|true|
|RAILS_LOG_TO_STDOUT|Value|true|
|DB_PASSWORD|ValueFrom|/fargate-test/db-password (パラメータストアの名前が入る)|
|DB_HOST|ValueFrom|/fargate-test/db-host|
|DB_USERNAME|ValueFrom|/fargate-test/db-username|
|RAILS_MASTER_KEY|ValueFrom|/fargate-test/rails-master-key|

イメージ
![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/a0e2ad93-2b3a-4f36-a691-3716c0ca3c9d.png)


この入力が完了したら更新します。


## Rails側の設定

今まで行った設定をもとにRailsファイルの編集とDockerfileの作成を行います。

### Database.ymlの編集
AWS RDSにつなぐために、database.ymlのProduction環境の設定を書き換えます。

```ruby
production:
  <<: *default
  database: fargate_test
  # 環境変数を読み込むように設定
  password: <%= ENV['DB_PASSWORD'] %>
  username: <%= ENV['DB_USERNAME'] %>
  host: <%= ENV['DB_HOST'] %>
```

### HealthCheck用のAPIを作成

`config/routes.rb`にhealth_check用のpathを追加

```ruby
  namespace :api do
    resources :health_check, only: :index
  end
```

`app/controllers/api/health_check_controller.rb`ファイル作成

```ruby
class Api::HealthCheckController < ApplicationController
  def index
    logger.info "============================================================"
    logger.info "ReuqestUrl: #{request.url}"
    render json: {status: 200}, status: 200
  end
end
```



### Dockerfile作成


```bash
# docker/productionフォルダを作成
mkdir -p docker/production/
# docker/productionフォルダにDockerfileを作成
touch docker/production/Dockerfile
```

### docker/production/Dockerfileの作成

```Dockerfile
FROM ruby:2.7.2 AS base

WORKDIR /app
ENV RAILS_ENV production
ENV NODE_MAJOR_VERSION 14
ENV BUNDLE_DEPLOYMENT true
ENV BUNDLE_PATH vendor/bundle
ENV BUNDLE_WITHOUT development:test
RUN gem update --system && gem install bundler:2.1.4

# builder
FROM base AS builder

RUN curl -sL https://deb.nodesource.com/setup_$NODE_MAJOR_VERSION.x | bash - && \
    curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
    echo 'deb http://dl.yarnpkg.com/debian/ stable main' > /etc/apt/sources.list.d/yarn.list && \
    apt-get update -qq && \
    apt-get install -y --no-install-recommends \
    vim locales build-essential curl libpq-dev libmariadb-dev nodejs yarn nginx sudo

# bundle
FROM builder AS bundle

COPY Gemfile Gemfile.lock .
RUN bundle install --jobs=4 --retry=3 && rm -rf $BUNDLE_PATH/ruby/$RUBY_VERSION/cache/*

# yarn
FROM builder AS yarn

COPY package.json yarn.lock .
RUN yarn install --production --frozen-lockfile && yarn cache clean

# main
FROM builder AS main

COPY . .

COPY --from=bundle /app/vendor/bundle /app/vendor/bundle
COPY --from=yarn /app/node_modules /app/node_modules

# nginx
RUN groupadd nginx
RUN useradd -g nginx nginx
ADD docker/production/nginx.conf /etc/nginx/nginx.conf
ADD docker/production/entrypoint.sh /app/entrypoint.sh

EXPOSE 80

RUN chmod +x /app/entrypoint.sh
```

### docker/production/entrypoint.shの作成
docker/productionフォルダにentrypoint.shファイル作成します。
コンテナ起動時に動かしたいコマンドを記述していきます

```shell
#!/bin/bash

sudo service nginx start
cd /app
RAILS_ENV=production bin/rails db:migrate
RAILS_ENV=production bin/rails assets:precompile
bundle exec pumactl start
```

### .dockerignoreの作成
Dockerのイメージに含めたくないファイルやフォルダを記載します

```.dockerignore
node_modules/
public/packs/
vendor/
log/
tmp/
!/tmp/pids/.keep
!/tmp/sockets/.keep
.git
.env
config/master.key
.github/
deploy/
spec/
storage/
```

### nginx.confの作成

docker/production/フォルダにnginx.confファイルを作成します。

ここにはNginxの設定を記載します

```Nginx
user nginx;
worker_processes auto;
error_log /dev/stderr info;
pid /var/log/nginx.pid;

events {
  worker_connections 1024;
}

http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;

  log_format json escape=json '{"time": "$time_iso8601",'
        '"remote_addr": "$remote_addr",'
        '"host": "$host",'
        '"http_host": "$http_host",'
        '"proxy_add_x_forwarded_for": "$proxy_add_x_forwarded_for",'
        '"scheme": "$scheme",'
        '"remote_user": "$remote_user",'
        '"status": "$status",'
        '"server_protocol": "$server_protocol",'
        '"request_method": "$request_method",'
        '"request_uri": "$request_uri",'
        '"request": "$request",'
        '"body_bytes_sent": "$body_bytes_sent",'
        '"bytes_sent": "$bytes_sent",'
        '"request_time": "$request_time",'
        '"upstream_response_time": "$upstream_response_time",'
        '"upstream_connect_time": "$upstream_connect_time",'
        '"upstream_addr": "$upstream_addr",'
        '"http_user_agent": "$http_user_agent",'
        '"http_referer": "$http_referer"}';

  access_log  /dev/stdout  json;

  sendfile        on;
  keepalive_timeout  65;
  include /etc/nginx/conf.d/*.conf;

  upstream app {
    server unix:///app/tmp/sockets/puma.sock;
  }

  server {
    listen 80 default_server;
    # 作成したロードバランサーのDNS名を記載します
    server_name fargate-test-421980051.ap-northeast-1.elb.amazonaws.com;
    root /app/public;

    location / {
      proxy_pass http://app;
    }

    client_max_body_size 100m;
    keepalive_timeout 5;
  }
}
```

### config/puma.rbの編集

一番下の行に以下を追記します

```ruby
app_root = File.expand_path('..', __dir__)
bind "unix://#{app_root}/tmp/sockets/puma.sock"
```

これで、ひとまずFargateでRailsを動かす設定は完了です。
DockerfileをBuildして、ECRにPushしていきましょう。

PushのコマンドはAWS管理画面のECRから確認することが可能です。
![Amazon_ECR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/ae6766d7-aa30-46df-243e-9f63ba6f3803.png)


```bash
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin #####
docker build -f docker/production/Dockerfile -t fargate-test .
docker tag fargate-test:latest #####.dkr.ecr.ap-northeast-1.amazonaws.com/fargate-test:latest
docker push #####.dkr.ecr.ap-northeast-1.amazonaws.com/fargate-test:latest
```

こんな感じのコマンドになります。
Pushが完了すると、ECRに以下のようにLatestタグで追加されます。
![Amazon_ECR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/9e567fa1-752d-b9e2-269e-6369fc819b13.png)


### 動きを確認

ここまでうまくできたら動きます。
作ったロードバランサーのDNS名にアクセスします。動いていたら成功です。

![EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/fb0890e5-e0db-8623-cf66-789c9dfc1f3d.png)


## ドメインを設定

現在はロードバランサーのDNS名がURLになっています。
これを自分で設定したドメインでアクセスできるようにしていきます。

今回は、お名前.com で購入したドメイン (hatsu38.com)にサブドメイン(fargate-test.)をつける設定を行っていきます。

### Route53でホストゾーンの作成

Route53の画面の以下のボタンからホストゾーンのページへ遷移します。

![Route_53_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/fc46b33a-41ce-6435-914f-35a1f6d99365.png)

ホストゾーンの作成では、以下の内容で作成を行います。

| フォーム | 値 |
| ---- | ---- |
|ドメイン名|fargate-test.hatsu38.com|
|説明|fargate-test.hatsu38.com|
|タイプ|パブリックホストゾーン|

![Route_53_Console_Hosted_Zones.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/4f64a0a8-f11c-28fe-9494-22c23985bc6e.png)

入力が完了したら、ホストゾーンの作成を実行します。

![Route_53_Console_Hosted_Zones.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/93924777-383b-c975-9d17-3bca388de162.png)


作成を行うと、NSレコードの値が4つ、SOAレコードの値が1つが確認できるかと思います。

このホストゾーンにAレコードの追加を行います。

![Route_53_Console_Hosted_Zones.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/56ecbd07-5b3a-fe8e-f706-e8738a8928fa.png)

上記から進むと、ルーティングポリシーの選択画面になります。
ここではシンプルルーティングを選択します。
![Route_53_Console_Hosted_Zones.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/9939b14a-145c-716b-c7ce-f1e2cef02f48.png)

さらに進みレコードタイプの選択を行います。

| フォーム | 値 |
| ---- | ---- |
|レコード名|空|
|レコードタイプ|Aレコード|
|値| Application LoadBarancer,ap-northeast-1,fargate-testのALB|

![Route_53_Console_Hosted_Zones.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/938c8fd9-b1cd-b75a-e478-635c3e4e23cc.png)

上記のように入力が済んだら、レコードの作成に進めます。

ここまで完了したらRoute53での作業は終了です。

続いてRoute53で確認したNSレコードの値をお名前.comに入力していきます。

#### お名前.comでの設定

お名前.comにログインしたら、以下のボタンからDNSの設定ページへ遷移します。

![ドメインNavi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/2e4a20dd-79e7-3689-b759-e8619173134f.png)

該当のドメインを選択して、次へ進みます

![ドメインNavi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/9a4925f3-59e6-4d1f-d93b-a47310ae531a.png)


続いて「DNSレコード設定を利用する」を押します。

![ドメインNavi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/8cdecbde-6890-b6fd-49cd-8c6aeed04d73.png)


するとホスト名などを入力する画面が表示されますので、Route53で確認した値を入力していきます。

|ホスト名 | TYPE |VALUE|
| ---- | ---- | ---- |
|fargate-test|NS|Route53で表示されていた ns-で始まる値|
|fargate-test|NS|Route53で表示されていた ns-で始まる値|
|fargate-test|NS|Route53で表示されていた ns-で始まる値|
|fargate-test|NS|Route53で表示されていた ns-で始まる値|

![ドメインNavi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/c72e6743-407d-33e5-ac98-d8bb8c3cb6a2.png)

上記のように入力が済んだら、一番下の「DNSレコード設定用ネームサーバー変更確認」のチェックだけ外して確認画面へ進み、設定を行います。

![ドメインNavi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/731160c6-fd93-5780-3851-4b2d5aa0d813.png)


### Nginxに対象のドメインドメイン追加

docker/production/nginx.conf というファイルに以下のような記述があったかと思います。

```nginx
  server {
    listen 80 default_server;
    # 作成したロードバランサーのDNS名を記載します
    server_name fargate-test-421980051.ap-northeast-1.elb.amazonaws.com;
    root /app/public;

    location / {
      proxy_pass http://app;
    }

    client_max_body_size 100m;
    keepalive_timeout 5;
  }
```

この `server_name` に対象のドメインの追加を行います。

```nginx
  server {
    listen 80 default_server;
    # 対象のドメインを指定
    server_name fargate-test.hatsu38.com fargate-test-421980051.ap-northeast-1.elb.amazonaws.com;
    root /app/public;

    location / {
      proxy_pass http://app;
    }

    client_max_body_size 100m;
    keepalive_timeout 5;
  }
```

ファイルの変更を行ったら再度 Dockerbuild~ECRへのPushの流れを行います。


### 再デプロイ

#### デプロイ時間の修正
現在のBlue/Greenデプロイの設定では、Blue(古いバージョン)からGreen(新しいバージョン)に切り替わるまで結構時間がかかります。デフォルトで1時間になっているので、まずはこちらの編集をしておきます。

まずは指定のアプリケーションの詳細を表示します。

![CodeDeploy_-_AWS_Developer_Tools.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/5b81199e-5587-b503-58ca-7851e62772e4.png)

続いてデプロイメントグループの編集です。

![CodeDeploy_-_AWS_Developer_Tools.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/46de2deb-8acb-4c88-bc43-8298d45184a9.png)

下の方にある「元のリビジョンの終了」の欄を、今回はテストなので「0時間０分」にしておきます。

![CodeDeploy_-_AWS_Developer_Tools.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/8ad0fafa-0b01-444c-1d5b-6dd98f5ca2ba.png)

この変更を完了したら、「変更の保存」を行います。

#### ECRへのPush
まずは以下の流れでECRへのPushを行います。

```bash
aws ecr get-login-password --region ap-northeast-1 | docker login --username AWS --password-stdin #####
docker build -f docker/production/Dockerfile -t fargate-test .
docker tag fargate-test:latest #####.dkr.ecr.ap-northeast-1.amazonaws.com/fargate-test:latest
docker push #####.dkr.ecr.ap-northeast-1.amazonaws.com/fargate-test:latest
```

Pushを実行すると　ECRの管理画面で Imageタグの行が2つに増えていると思います。

![Amazon_ECR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/26f5a1e0-8d45-7564-2898-337a4b8a71a4.png)

ECRのPushをしたら、そのDockerイメージをECS ServiceやTaskが利用できるようしていきます。

#### ECS Serviceの更新

該当のECS Serviceにチェックを入れて更新をします

![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/43633162-8595-c00a-4cdd-562d6ed60537.png)

更新に進むと、リビジョンの選択ができると思います。
こちらのリビジョンを `Latest` にする、 `新しいデプロイのの強制`にチェックを入れます。
ほかはそのままで問題ありません。

![Amazon_ECS.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/f7adc625-3d2f-cf5b-bc27-726517349ab3.png)

全部進めたら「サービスの更新」を行ってください。

これでドメイン設定の作業は完了です。数時間待つとドメインが反映されるかと思います。

![FargateTest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/dfe71da0-c768-fe51-d862-97ade8f1d3a5.png)


## HTTPSでアクセスできるようにSSL化

現在はhttp:// であり、 https:// ではアクセスできません。

ここではHTTPSでアクセスできるようにしてきます。

HTTPSにするために必要な証明書は、AWS Certificate Managerというサービスで作成が可能です。
この作業を行っていきます。

### SSL証明書の作成

Certificate Managerから「証明書のリクエスト」を行います。

![AWS_Certificate_Manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/310a6627-3113-2be8-6ee1-0eb452276432.png)

パブリック証明書のリクエストを選択して「証明書のリクエスト」を行います。

![AWS_Certificate_Manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/878b13cc-58cc-9ded-cebe-532b633069a2.png)

続けてドメイン名を入力します。

![AWS_Certificate_Manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/af1447eb-89e5-2bed-b1b6-3d44576b0ba9.png)

続けて DNSの検証 を選択します。

![AWS_Certificate_Manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/8dd9d8a2-311d-5e99-7e0d-31cd6fabcca8.png)


タグ名は、からのまま次に進めます。
確認画面までいったら、「確定とリクエスト」を実行して完了です。

![AWS_Certificate_Manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/3429d28b-f07a-8bcf-3bd0-8942bf17b691.png)

作ってすぐは「検証保留中」のステータスになっています。

![AWS_Certificate_Manager.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/abd6b1ad-02d0-3bf0-fb17-f163fdc8e0c0.png)

ここで「Route53でのレコードの作成」を実行します。

また、ドメインの詳細にある、名前、種類、値を参考にお名前.coｍに設定を追加します。


### お名前.comでの設定
ホスト名に名前、TYPEはCNAME、値に値を入れます。

![ドメインNavi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/117e9ee9-96f4-e23b-e34f-bf187e3649c4.png)


入力したら設定を完了します。


### ロードバランサーの編集

作ったロードバランサー「fargate-test」のリスナーに「HTTPS」を追加していきます。

以下から「リスナーの追加」を行います。
![EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/93de856a-1320-66f1-45b1-4e432957d4e1.png)

リスナー追加画面では、以下の内容を入力します。

|  フォーム  |  値  |
| ---- | ---- |
|プロトコル：ポート|HTTPS:443|
|アクションの追加|転送先|
|ターゲットグループ : 重み (0～999)|fargate-test|
|セキュリティポリシー|ELBSecurityPolicy-FS-1-2-2019-08|
|デフォルトの SSL 証明書|ACMから：fargate-testを選択(Certificate Managerで作った証明書を選択)|

![リスナー___EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/0d088570-15ed-17ad-c0e1-59ae6c0578d9.png)

上記のように入力が完了したら、リスナーを追加します。

#### セキュリティグループの編集
現在はセキュリティグループでHTTPSを受け付けていません。
HTTPSでもアクセスできるように編集していきます。

セキュリティグループの画面へ行き、「fargate-test」を選択し、インバウンドルールを編集します。

![EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/3deb58d6-9549-1da7-0e60-3f34c647b49f.png)

インバウンドルール編集画面では、タイプに「HTTPS」を選択してCIDRブロックには「0.0.0.0/0,::/0」の2つを選択します。

![EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/0cfcd00c-73cf-5565-991a-f1402aabfd90.png)

上記の入力が完了したら「ルールを保存」を実行します。

これで設定が完了です。 https:// のURLで表示できるようになると思います。


## HTTPでアクセスできないようにする

### ロードバランサーのHTTPリスナーを編集

HTTPリスナーのルールを編集します。
以下のボタンから編集が可能です。
![ロードバランサー___EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/5781a18d-ef73-fd45-e306-257f3541b78b.png)

この画面に来たらルールの挿入を行います。
![ルール___EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/7af7b223-8c9e-1ad7-5c62-b127382e4682.png)

パスを `/*`にして、 アクションは「リダイレクト先」を選択します。
HTTPSプロトコルを選択し、ポートは443を入力します。

![ルール___EC2_Management_Console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107345/c950e46d-e18c-d7a7-49f5-af1ca837d468.png)

入力が完了したら保存して終了です。


### アプリケーションの編集

こちらはアプリケーションとNginxの方で対応します。

#### Railsをforce_sslにする
まずは config/environments/production.rb に以下のようなコメントアウトされたコードがあると思いますので、

```ruby
# config.force_ssl = true
```
以下のようにコメントを外します。

```ruby
config.force_ssl = true
```

#### NginxをSSLにする

docker/production/nginx.confを編集します

```nginx
  server {
    listen 80 default_server;
    # ↓443を追加
    listen 443 default_server;
    server_name fargate-test.hatsu38.com fargate-test-421980051.ap-northeast-1.elb.amazonaws.com;

    # ここから
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect off;
    # ここまで追加

    root /app/public;

    location / {
      proxy_pass http://app;
    }

    client_max_body_size 100m;
    keepalive_timeout 5;
  }
}
```

ここまでできたら、再度デプロイを行ってください。

デプロイが完了すると、http://で始まるURLでアクセスしてもhttps://のURLに変わっているかと思います。


## 終わりに
長かったっですが、以上でRailsをFargateで動かす手順が完了です。
次は、このデプロイをGithubActionsで自動デプロイできるようにしていきます。

こちらの記事↓

https://qiita.com/hatsu/items/a70d5c49a39561836751

Sidekiqの導入はこちら↓

https://qiita.com/hatsu/items/013271e93f9138594420


Terraformで構築するバージョンはこちら↓

https://qiita.com/hatsu/items/8b30e68ba7252a749fe7