ACMとELBを使いEC2サーバの証明書を一つにまとめる

# 概要

これまでEC2サーバ毎(コーポレートサイト、Redmine、GitLab等)にサーバ証明書を発行しており、証明書の更新作業が煩雑になっていました。
今回、EC2サーバにロードバランサーを挟むことでサーバ証明書を一つにまとめる作業を実施しました。


## 以前のサーバ構成

下記図のようにEC2サーバそれぞれが独立し、サーバ証明書を別々に使用している状態となっていました。

- https://○○○(ドメイン名).co.jp
- https://redmine.○○○(ドメイン名).co.jp
- https://gitLab.○○○(ドメイン名).co.jp etc...


![サーバ構成図_作業前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682549/d3438db5-b171-e1a6-90c0-1bb6c6172506.png)


## 今回の作業後のサーバ構成

下記図のようにELBを挟み、ACMから発行されるサーバ証明書一つに設定しました。
Gitlabについては、以前のサーバ構成のままとしました。
理由については後述(補足②)します。

![サーバ構成図_作業後.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/682549/33af62c5-d4a9-decd-d4cd-d8f0fb4d6dc4.png)


## 今回の作業で使用しているAWSサービス

- EC2
- ELB
- Route53
- ACM

# 前提知識

## ACMとは？

AWSのサーバ証明書サービスです。
ELB、CroudFront、APIGatewayのAPIなどACMに統合されたAWSリソースでデプロイできます。

## ELBとは？

ELBとはALB、NLB、CLBの総称です。

- ALB(Application Load Balancer)
  - アプリケーションレイヤー(HTTP/HTTPS)でルーティング
  - L7リバースプロキシ
- NLB(Network Load Balancer)
  - トランスポートレイヤー(TCP/SSL)でルーティング
  - L4 NAT ロードバランサ
  - TCPに対応
- CLB(Classic Load Balancer)
  - トランスポートレイヤー(TCP/SSL)または(HTTP/HTTPS)のいずれかでルーティング
  - L4/L7 リバースプロキシ
  - TCP, SSL, HTTP, HTTPSに対応


# 手順

## 前提条件

- ホストゾーン、レコード設定は既にされているものとします<br>
  (以前のサーバ構成に記載の図の状態にて既に作成されているため)
- 記載の手順に関して
  - 今回は、各AWSサービスの詳細な手順(画面毎の設定)までは記載しません
  - VPC、セキュリティグループ等は、それぞれ適切なものを設定してください

※実作業ではすでに作成されているALBが存在していたので、そちらを使用しましたが、
手順ではLoadBalancerの作成から記載しています。

## 1. ACMのサーバ証明書発行

- Certificate Managerからパブリック証明書のリクエストを実施
  - ドメイン名は「○○○(ドメイン名).co.jp」と「*.○○○(ドメイン名).co.jp」を登録<br>
    (ワイルドカードを使い「www.○○○(ドメイン名).co.jp」や「redmine.○○○(ドメイン名).co.jp」にも適用できるようにします)
- 検証の実施(今回はDNSの検証にて実施)

## 2. Load Balancerの作成

- ロードバランサーの種類の選択
  - 「Application Load Balancer」を選択
  - 名前(今回は「○○○(ドメイン名)-elb」としました)
  - ロードバランサーのプロトコルはHTTP(ポート80)

## 3. ターゲットのグループの作成

- ターゲットグループ名：「○○○(ドメイン名)TG」、Redmineの場合は「RedmineTG」etc...としてそれぞれ登録
  - ターゲットの種類：インスタンス
  - プロトコル：HTTP
  - パス： /
  - ポート：80

## 4. Load Balancerのリスナーを追加し、ターゲットと紐付ける

- ロードバランサーのリスナータブからhttps(ポート443)を追加
- 追加したリスナーに「証明書の表示/編集」を押下し、手順1にて発行したACMと紐付ける
- 「ルールの表示/編集」を押下し、手順3で作成したターゲットグループを紐付ける
    - ○○○(ドメイン名).co.jpの場合
     - IF：ホストが○○○(ドメイン名).co.jp
     - THEN 転送先：○○○(ドメイン名)TG
  - redmine.○○○(ドメイン名).co.jpの場合
     - IF：ホストがRedmineTG
     - THEN 転送先：RedmineTG

※ここでは、一番上にあるものから順に処理されます。

## 5. Route53のエイリアスをLoadBalancerに変更する

- ○○○(ドメイン名).co.jpのタイプAを選択し、下記設定を行います
  - エイリアス：はい
  - エイリアス先：作成したロードバランサー(○○○(ドメイン名)-elb)
- redmine.○○○(ドメイン名).co.jp等も同様に設定する

# 補足① メンテナンス画面の作成

アプリケーションロードバランサーは、簡単にメンテナンス画面を表示させることもできます。

1. ロードバランサーの設定画面に遷移し、上記手順にて作成したロードバランサーを選択
2. リスナーのルールの表示/編集をクリック
3. 新規で下記2点を作成
    - 社内からのみメンテナンスする環境にアクセス可能にする
        - IF: ホストが○○○(メンテナンスする環境のドメイン).co.jp、送信元IPが○○○.○○○.○○○.○○○/32(作業する環境のGIP)
        - THEN: ○○○(メンテナンスする環境のドメイン)TG
    - メンテナンス画面の作成
        - IF: ホストが○○○(メンテナンスする環境ドメイン).co.jp
        - THEN：固定レスポンスを返す→メンテナンス画面のhtmlを作成
4. 手順3にて作成したルールを一番上に持っていく。
   (一番上のものから優先的に処理されるので、こちらを利用します)

※ メンテナンス中のhtml例

- レスポンスコード： 503
- Content-Type: text/html
- レスポンス本文

```
<pre>
<html>
<head>
<meta charset="utf-8">
<title>Maintenance</title>
</head>
<body>
<p style="text-align: center;">
<span style="font-size: large;">ただいま緊急メンテナンス中です。</span><br />
<span style="font-size: large;">メンテナンス終了予定時刻 : </span><br />
<span style="font-size: xx-large;">2020/07/16 12:00 </span><br />
</p>
</body>
</html>
</pre>
```

# 補足② GitLabに関して

GitLabもELBにまとめる予定でしたが、現在のELBはALBを使っており、GitLabのSSH接続ができません。
CLB環境を構築することも考えましたが、コスト面から、今回はGitLabのみ以前の構成のままとしました。

# 参考記事

https://aws.amazon.com/jp/elasticloadbalancing/
https://aws.amazon.com/jp/elasticloadbalancing/pricing/
https://qiita.com/wakky_404/items/e082b7545801cf25905c