【ポートフォリオをECSで！】Rails×NginxアプリをFargateにデプロイするまでを丁寧に説明してみた(VPC作成〜CircleCIによる自動デプロイまで) 後編

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/92672c4e-a8b8-1b8c-003b-ef19c3b35b58.png)

# 概要
↓前編

https://qiita.com/maru401/items/8e7d32a8baded045adb2

後編では、独自ドメインの取得〜CircleCIの自動デプロイの設定まで行いたいと思います。

【前編】

- 1.VPCの設定
- 2.RDSの設定
- 3.ECRの設定
- 4.ECSの設定

【後編】

- 5.独自ドメインの設定(お名前ドットコム)
- 6.ACMの設定
- 7.ALBの設定
- 8.CircleCIの設定


## 5.独自ドメインの取得(お名前ドットコム)
前編でパブリックIPでFargateにデプロイしたアプリにアクセスできましたが、ここから独自ドメインを使ってアクセスできるように設定していきます。
以下のお名前ドットコムにアクセスして独自ドメインの設定をしていきましょう。

https://www.onamae.com/

### 5.1 独自ドメインの設定

お名前ドットコムにアクセスしたら検索バーに取得したいドメインを入力し検索ボタンを押します。
筆者は`modern-tech.work`を選択しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/e9ba6a6b-c457-bc45-d5bf-c4a2d2de985e.png)

次に希望のドメインにチェックを入れてください。2のサーバーは`利用しない`を選択してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/56becc3d-58ff-a7d6-d4f5-1038684d7f2b.png)

お申し込む内容確認画面に飛ぶので、ログインして購入画面に進みます。`Whoisメールとドメインプロテクション`は好みに合わせてチェックしてください。はじめの利用する場合は初めてご利用する方を選択して、登録を行ってください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/9e07f0dd-009c-b25b-edaf-1f6cea8f0725.png)

支払い方法を登録して申し込むをクリックすることで申し込みが完了します。
※ ドメインを取得して一定時間後、ドメインの取得認証のメールアドレスが登録したメールアドレス宛に送信されます。
こちらの認証がメールが届いてから2週間以内に行われない場合、ドメインが使用不可になってしまいますので注意してください。
(筆者はこちらが原因でサーバーが止まり原因特定にかなりの時間を要しました汗)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/4daa7dd5-00ce-0bb3-d63d-c61c3009b45a.png)

この後、以下のお名前ドットコム.naviにアクセスして操作をしていきますのでリンクを他のタブで開いておいてください。

https://navi.onamae.com/top

### 5.2 Route53のホストゾーンの設定
Route53のホストゾーンの設定を行います。
AWSに戻り、サービスからRoute53を選び、`Route53→ホストゾーン→ホストゾーンの作成`で選択します。
そして以下のように設定をし、ホストゾーンの作成をクリックします。

|  タグ  |  値  |
| ---- | ---- |
|  ドメイン名  |  お名前ドットコムで取得したドメイン名  |
|  説明  |  適当  |
|  タイプ  |  パブリックホストゾーン  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/1f1c8d23-18a5-5c0b-7c48-435c015b2e2d.png)

### 5.3 ネームサーバーの設定
5.2で作成したホストゾーンを選択して詳細画面に飛んでください。
タイプが`NS`のルーティング先4つを`最後の.を省いて`コピーしてください。
例えば、`xxx-00.org.`であれば`xxx-00.org`という感じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/f4a7e2ba-65ef-349e-4653-334b5cd5fec4.png)

コピーが終わったら他のタブで開いておいたお名前ドットコム.naviに移動します。
`ドメイン→利用ドメイン一覧→取得したドメイン→ネームサーバー情報→ネームサーバーの変更`で選択し、`その他→その他ネームサーバーを使う`より先程Route53でコピーした4つのネームサーバーを入力します。入力が完了したら確認をクリックしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/26e3f1ab-efff-7e45-c66d-fc9067c84067.png)

ネームサーバーの登録完了したら以下のコマンドをローカルターミナルで叩きRoute53のネームサーバーがドメイン名と紐付いているか確認してください。`こちらは . が最後に入っています`

```:terminal
dig 取得したドメイン名 NS +short
```

## 6.ACMの設定
AWS Certificate Manager(ACM)はSSL証明書発行サービスです。AWS内のサービスにSSLを適用させなければいけない制約はあるもののACM自体は無料で利用することができます。

### 6.1 ACMのリクエスト
サービスからACMを検索し、`ACM→証明書のリクエスト`を選択します。
パブリック証明書を選択して証明書のリクエストをクリックします。
ドメインの追加画面になったら以下のように設定を行います。
`*.取得したドメイン名`をドメイン名に追加することで、`www.modern-tech.work`のようなサブドメインを設定することが可能になります。これにより、サブドメインを設定することで無限にドメインを追加する事ができるようになります。

|  ドメイン名  | 
| ---- | 
|  取得したドメイン名  |  
|  *.取得したドメイン名  |  

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/f37955c2-0bce-15b5-e8ce-b9a96f08e1f0.png)

検証の選択は`DNSの検証`を選択し次へをクリックします。
タグの追加で以下のようにタグを設定し確認をクリックします。

|  タグ  |  値  |
| ---- | ---- |
|  タグ名  |  sample-acm  |

確認画面に行くので、確定とリクエストをクリックしてSSL証明書の発行を行います。
検証保留中の画面になるので続行を押して検証が完了するまで待ちます。
6.2のRoute53のレコードの追加に使いますのでDNS設定をファイルにエクスポートを押してCNAMEレコードの設定ファイルをダウンロードしてください。
そして、取得したDNS設定ファイルの`レコード名・レコードタイプ・レコードバリュー`の3つをコピーしてください。(取得したドメイン名と*.取得したドメイン名で同じになってるはずです)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/a71765b6-1bd0-1505-b362-eaeaff820fd4.png)

### 6.2 ACMにCNAMEレコードを追加
`Route53→ホストゾーン→取得したドメイン名`を選択し、`レコードを作成`をクリックします。

|  タグ  |  値  |
| ---- | ---- |
|  レコード名  |  コピーしたレコード名のドメイン名より前の部分  |
|  レコードタイプ  |  CNAME  |
|  値  |  コピーしたレコードバリュー(最後の.も含めます)  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/77fd9a5e-d89e-6688-d3df-cdb2662d717e.png)

## 7.ALBの設定
ECSのクラスターを形成する際にロードバランサーが必要になります。
ロードバランサーとはサーバーに掛かる負荷を分散することで、1つあたりのサーバーに掛かる負荷を抑えるものです。
これにより、サーバー一つにかかる負荷が小さくなりサーバーダウンが防げます。

### 7.1 ALBのセキュリティグループの作成
`VPC→セキュリティグループ→セキュリティグループの作成`を選択します。

|  タグ  |  値  |
| ---- | ---- |
|  名前  |  sample-alb-security  |
|  説明  |  適当  |
|  VPC  |  sample_vpc   |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/0fd4b7bd-36db-7ee5-46c4-f9ce529801ac.png)

インバウンドルールは以下のようにhttp通信とhttps通信ができるように2つ設定します。

|  タグ  |  値  |
| ---- | ---- |
|  タイプ  |  HTTP  |
|  リソースタイプ  |  任意の場所  |

|  タグ  |  値  |
| ---- | ---- |
|  タイプ  |  HTTPS  |
|  リソースタイプ  |  任意の場所  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/6c410535-2dfd-535d-8a5c-b54e7d1349f5.png)

アウトバウンドルールは以下のようにECSのセキュリティグループへのみ通信を制御するようにデフォルトの設定を削除して以下の設定を追加します。
設定が完了したらセキュリティグループを作成をクリックします。

|  タグ  |  値  |
| ---- | ---- |
|  タイプ  |  HTTP  |
|  送信先タイプ  |  カスタム  |
|  送信先  |  sample_ecs_security  |


### 7.2 ALBの作成
※この作業はSSL証明書の発行が完了しないとできないためACMからリクエストした証明書が発行されていることを確認してから実行してください。

`EC2→ロードバランサー→ロードバランサーの作成`を選択します。

最終的に独自のドメインを取得し、HTTPS通信することを目標とするのでApplication Load Balancer(ALB)を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/d56cfb93-6b65-d32f-1db9-d7e87b2ee898.png)

ロードバランサーの設定は以下のようにします。
アドオンサービスの設定はチェックせずに次の手順へ進みます。

|  タグ  |  値  |
| ---- | ---- |
|  名前  |  sample-alb  |
|  リスナー  |  HTTP, HTTPS(ポートは勝手に選択されます)  |
|  VPC  |  sample_vpc   |
|  アベイラビリティゾーン  |  ap-northeast-1a(sample_public_subnet1), ap-northeast-1c(sample_public_subnet2) |
|  ログ設定  |  ON   |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/4343a23e-c640-cc88-327b-a6662c632589.png)

セキュリティ設定の構成は以下のように設定します。
セキュリティポリシーはAWSで推奨されているデフォルトのELBSecurityPolicy-2016-08で次の手順に進みます。

|  タグ  |  値  |
| ---- | ---- |
|  証明書タイプ  |  ACMから証明書を選択します |
|  証明書の名前 |  発行した証明書  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/3222818e-edc3-80f1-65a7-0da558ac0095.png)

セキュリティグループの設定は7.1で作成した`sample-alb-security`を選択して次の手順に進みます。

ルーティングの設定は以下のようにします。ヘルスチェックはルートパスで行われるように設定しています。設定が完了したら次の手順へ進みます。

|  タグ  |  値  |
| ---- | ---- |
|  ターゲットグループ  |  新しいターゲットグループ  |
|  名前  |  sample-target  |
|  ターゲットの種類 |  IP  |
|  プロトコル |  HTTP  |
|  ポート |  80  |
|  プロトコルバージョン |  HTTP1  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/607054b0-99ad-6eb5-f5ce-c13970beb069.png)

ターゲットは登録せずに確認をして作成を行ってください。

### 7.3 ALBを含めたECSのサービスの作成
`ECS→クラスター→sample-cluster`を選択してくだい。
そして、前編の4章で作成したsample-serviceを削除して新しいサービスを作成します。sample-serviceを削除した後、`サービス→作成`を選択します。

サービス設定は以下のように行い次のステップに進みます。

|  タグ  |  値  |
| ---- | ---- |
|  起動タイプ  |  FARGATE  |
|  タスク定義 ファミリー  |  sample  |
|  タスク定義 リビジョン  |  latest  |
|  クラスター  |  sample-cluster  |
|  サービス名  |  sample-alb-service  |
|  タスクの数  |  1  |


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/2b118830-e80d-b8df-82b4-4220b52dde69.png)

ネットワーク構成は以下のように行います。

|  タグ  |  値  |
| ---- | ---- |
|  クラスターVPC  |  sample_vpc  |
|  サブネット  |  sample_public_subnet1  |
|  セキュリティグループ  |  sample_ecs_security  |
|  パブリック IP の自動割り当て  |  ENABLED  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/ad3fe1b1-1a57-5fe2-ec12-6f228115b7d1.png)

今回はロードバランサーの設定も加えます。

|  タグ  |  値  |
| ---- | ---- |
|  ロードバランシング  | Application Load Balancer  |
|  ロードバランサー名  |  sample-alb  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/f1645e40-49a2-af09-69da-48ea9e4d048e.png)

ロードバランス用コンテナにnginxが選択されていると思うのでロードバランサーに追加をクリックします。
その後、ターゲットグループ名を`sample-target`として次のステップに行きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/69d4e142-585b-78ee-0ee8-fc657fc0069f.png)

Auto Scalingの設定は今回はしないでサービスを作成します。
サービスが起動するまで待ちましょう。

### 7.4 ドメインとロードバランサーの結びつけ
最後に独自ドメインからサービスにアクセスできるようにロードバランサーと結びつけをします。
`Route53→ホストゾーン→取得したドメイン名→レコードの作成`を選択します。
以下のように設定します。

|  タグ  |  値  |
| ---- | ---- |
|  レコード名  |  空  |
|  レコードタイプ  |  A  |
|  トラフィックのルーティング先  |  エイリアスON→Application Loadbalancer→ap-northeast-1→sample-alb  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/db2b67ec-8945-2208-8aee-bab821e9aeff.png)

また、サブドメインからもアクセスできることを確認するため以下のレコードもついでに追加します。

|  タグ  |  値  |
| ---- | ---- |
|  レコード名  |  www  |
|  レコードタイプ  |  A  |
|  トラフィックのルーティング先  |  エイリアスON→Application Loadbalancer→ap-northeast-1→sample-alb  |


ここまでの設定が完了したら`http(s)://ドメイン名`で検索してみてください。以下のようにアプリが開ければ成功です。
また、`http(s)://www.ドメイン名`でも同様にアプリが開けることを確認してください。

※もし開けない場合、route53の設定が誤っていないか確認してみてください。また、ドメインがお名前ドットコムから発行されてからインターネットで使用できるようになるためタイムラグ(最大1日)が発生するのでしばらく待ってからアクセスを試みてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/e46bdc22-e501-ecf5-c701-1d5a4990689f.png)

##### ルーティングの整備
httpsでの通信が確認できたらhttp通信があると暗号化されない通信に間違ってアクセスしてしまう可能性があるので、http通信を遮断します。
ALBのセキュリティグループの`sample-alb-security`にアクセスしインバウンドルールの編集を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/d4edafba-eb2d-1064-7758-32cedf9721e8.png)

インバウンドルールが編集語に以下のようになっているのを確認してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/6643f9cf-71c6-821b-9308-f1385de48c8c.png)

再び、`https://ドメイン名`にアクセスしてアプリが表示されることを確認してください。また、`http://ドメイン名`にアクセスしてアクセスできなくなっていることを確認してください。

## 8.CircleCIの設定
最後にCircleCIの設定です。
こちらを設定することによりECSの自動デプロイが可能になります。


### 8.1 CircleCIのファイルを作成する
以下のようにCircleCIのファイルを作成してください。
今回はcircleciの自動デプロイをmasterブランチに限定しました。

```:.circleci/config.yml
version: 2.1

orbs:
  aws-ecr: circleci/aws-ecr@6.15
  aws-ecs: circleci/aws-ecs@2.0.0
workflows:
  # Nginxのデプロイ
  nginx-deploy:
    jobs:
      - aws-ecr/build-and-push-image:
          #AWS_ECR_ACCOUNT_URL => ${アカウントID}.dkr.ecr.${リージョン}.amazonaws.com
          account-url: AWS_ECR_ACCOUNT_URL
          # リージョン
          region: AWS_REGION
          aws-access-key-id: AWS_ACCESS_KEY_ID
          aws-secret-access-key: AWS_SECRET_ACCESS_KEY
          # ECRにリポジトリがなかったら創るか？
          create-repo: true
          # Dockerfleのパス(デフォルトはカレントディレクトリのパス)
          dockerfile: ./nginx/Dockerfile
          # ECRのリポジトリ
          repo: nginx-sample
          tag: "${CIRCLE_SHA1}"
          filters:
            branches:
              only: master
      - aws-ecs/deploy-service-update:
          requires:
            - aws-ecr/build-and-push-image
          # ECSのタスク定義名
          family: 'sample'
          # ECSのクラスター名かARNのフルパス
          cluster-name: 'sample-cluster'
          # サービス名
          service-name: 'sample-alb-service'
          # containerはタスク定義で設定したコンテナ名にする
          container-image-name-updates: "container=nginx,tag=${CIRCLE_SHA1}"

  # Railsのデプロイ
  rails-deploy:
    jobs:
      - aws-ecr/build-and-push-image:
          account-url: AWS_ECR_ACCOUNT_URL
          region: AWS_REGION
          aws-access-key-id: AWS_ACCESS_KEY_ID
          aws-secret-access-key: AWS_SECRET_ACCESS_KEY
          # ECRにリポジトリがなかったら創るか？
          create-repo: true
          dockerfile: ./Dockerfile.prod
          # ECRのリポジトリ
          repo: rails-sample
          tag: "${CIRCLE_SHA1}"
          filters:
            branches:
              only: master
      - aws-ecs/deploy-service-update:
          requires:
            - aws-ecr/build-and-push-image
          # ECSのタスク定義名
          family: 'sample'
          # ECSのクラスター名かARNのフルパス
          cluster-name: 'sample-cluster'
          # サービス名
          service-name: 'sample-alb-service'
          # containerはタスク定義で設定したコンテナ名にする
          container-image-name-updates: "container=rails,tag=${CIRCLE_SHA1}"
```

### 8.2 CircleCIの環境変数を設定
まずは以下のURLからCircleCIのプロジェクトにいき、`Set Up Project`をクリックして対象のリポジトリをCircleCIが適用できるように設定します。


https://circleci.com/

そして、環境変数に以下を設定します。

|  環境変数  |  値  |
| ---- | ---- |
|  AWS_ACCESS_KEY_ID  |  IAMのアクセスキーID  |
|  AWS_SECRET_ACCESS_KEY  |  IAMのシークレットアクセスキー  |
|  AWS_REGION  |  ECR・ECSを作成したリージョン(ap-northeast-1)  |
|  AWS_DEFAULT_REGION  |  ECR・ECSを作成したリージョン(ap-northeast-1)  |
|  AWS_ECR_ACCOUNT_URL  |  {IAMのアカウントID(数字だけのやつ)}.dkr.ecr.{IAMのリージョン}.amazonaws.com  |

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/e47ba8cd-1bdc-635a-e858-fc7baedd3bbc.png)


### 8.3 CircleCIの自動デプロイテスト
試しにヘッダーの色を黄色に変更してgithubにプッシュしてみます。
みなさんも自分のアプリの一部を変更して自動デプロイができるか確かめてみましょう。
変更が済んだら以下のようにコマンドを叩きgithubへプッシュします。

```:terminal
git checkout master
git add .
git commit -m "ciecleci sample test"
git push origin master
```

CircleCIのダッシュボードに行き自動デプロイがsuccessになっているのを確認してください。
以下のようになっていれば成功です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/8aa204ac-b21e-2a6d-8efa-4ccbe2e1e50f.png)

CircleCIの自動デプロイが完了しているのを確認したら`http://ドメイン名`にアクセスして変更が適用されているか確認しましょう。
これで全ての工程は終了です。お疲れさまでした。
もし、使わなくなった場合は結構お金を持っていかれるので作成した構成を削除してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/656158/3c997a71-29e5-f8a2-d20e-8310bb9ac85a.png)

## おわり
ここまで長かったですがECSの自動デプロイまで説明してきました。
AWSの構成の仕方で途中でエラーが出たり、不具合があった場合はコメントを残してくださると幸いです。
よかったらLGTMをお願いします！！