無料！かつ最短？で Ruby on Rails on Docker on AWS のアプリを公開するぞ。

# はじめに
個人開発向けにRuby on Rails on Docker on AWSのアプリ公開までをまとめてみます。
AWSの無料枠の範囲内、ドメインはFreenom、SSL証明書はACMを使うことで全部無料をめざします。
AWSの無料枠については「[AWS クラウド無料利用枠 | AWS](https://aws.amazon.com/jp/free/?all-free-tier.sort-by=item.additionalFields.SortRank&all-free-tier.sort-order=asc&awsf.Free%20Tier%20Types=categories%23featured)」を参照です。（AWSの無料枠はアカウント作成から1年間限定です！）

# 全体像
めざす姿はこんな感じ。
![Untitled Diagram (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/600ff96d-16b5-c946-3d7b-1036465df2f9.png)

AWS上に、「ALB + EC2 + RDS」の環境を作ります。ALBにACMを適用してHTTPSでサービス提供します。EC2上にDockerを展開しまして、NGINXコンテナで受けてRailsコンテナに受け渡します。DBはRDS（PostgreSQL）を使います。
基本的なRailsコンテナは「[Quickstart: Compose and Rails | Docker Documentation](https://docs.docker.com/compose/rails/)」にそってます。NGINXとRailsのコンテナの作り方については、「[Nginx + Rails (Puma) on Docker のいくつかの実用パターン - Qiita](https://qiita.com/na-o-ys/items/1a863419e1f6c3063ace)」を参考にさせていただいてます。

GitはGitlabを使います。EC2からアプリをpullします。

# 事前準備
以下の手順はこの記事では省略します。
+ AWSアカウントの作成
+ Gitlabアカウントの作成
+ Gitlabのリポジトリにアプリをpush済み

# 全体の手順
1. RDSインスタンスの作成
2. EC2インスタンスの作成
3. ALBの作成
4. ドメインの適用（Freenom）
5. HTTPS化

簡単5ステップ！（ここから長いです笑）

# 1. RDSインスタンスの作成

## 1-1. RDSを作成する
まず、AWSコンソールにログインします。（[クラウドならアマゾン ウェブ サービス 【AWS 公式】](https://aws.amazon.com/jp/?nc2=h_lg)）
【サービス】で「RDS」で検索するなどして、【Amazon RDSダッシュボード】にアクセスします。ここで【データベース】メニューを選び、【データベースの作成】を選択することでRDS作成フローに入ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/836aa4e0-9cf9-fd0c-d2ec-8ec21135152b.png)


### ステップ１：エンジンの選択
まずページの下部に【RDS無料枠の対象オプションのみ有効化】というチェックボックスがあるのでこちらにチェックを入れます。これで安心して無料枠対象のRDSを作成することができます。
その後、【PostgreSQL】を選択して、【次へ】を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/8e79d709-54bb-60a2-59fc-0eb5aa69f57a.png)

### ステップ２：DB詳細の指定
以下の設定をして【次へ】を選択します。ステップ１で【RDS無料枠の対象オプションのみ有効化】を選択しているので、無料枠の対象オプション以外のオプションは非活性になっているはずです。

|項目|設定値|
|:---|:---|
|ライセンスモデル|postgresql-license|
|DBエンジンのバージョン|どれでも（開発環境で使っているDockerイメージのバージョンに合わせる）|
|DBインスタンスのクラス|db.t2.micro - 1vCPU, 1GiB RAM|
|マルチAZ配置（非活性）|いいえ|
|ストレージタイプ（非活性）|汎用（SSD）|
|ストレージ割り当て|20 GiB|
|DBインスタンス識別子|おまかせ|
|マスターユーザの名前|おまかせ|
|マスターパスワード|おまかせ|
|パスワードの確認|マスターパスワードを入力|

## ステップ３：詳細設定の設定
以下の設定をして【データベースの作成】を選択します。基本的にデフォルトのままで「データベースの名前」だけつけてあげます。

|項目|設定値|
|:---|:---|
|Virtual Private Cloud (VPC)|デフォルトVPC|
|サブネットグループ|default|
|パブリックアクセシビリティ|いいえ|
|アベイラビリティゾーン|どれでも|
|VPCセキュリティグループ|新規のVPCセキュリティグループを作成|
|データベースの名前|おまかせ|
|ポート|5432|
|DBパラメータグループ|default.postgres10|
|オプショングループ（非活性）|default:postgres-10|
|IAM DB認証|無効化|
|暗号化（非活性）|暗号化を無効にする|
|バックアップの保存期間|7日間|
|バックアップウィンドウ|指定なし|
|タグをスナップショットへコピー|チェックする|
|拡張モニタリング|拡張モニタリングを有効にする|
|モニタリングロール|デフォルト|
|詳細度|60秒|
|パフォーマンスインサイト|パフォーマンスインサイトの有効化|
|保持期間|デフォルト（7日）|
|マスターキー|(default) aws/rds|
|ログのエキスポート|すべてチェックしない|
|マイナーバージョン自動アップグレード|好きな方を選択|
|メンテナンスウィンドウ|指定なし|
|削除保護|「削除保護の有効化」にチェック|

これでRDSの作成が完了しました。
【データベース】メニューにレコードが追加されています。【ステータス】が【利用可能】になったら完成です。

## 1-2. database.ymlを設定する
ここまでで作成したRDSの情報をproductionのDBとして`config/database.yml`にて設定します。ただし、公開する情報ではないのでcredentialsで隠しておきます。まずはcredentialsの設定をします。

```bash
docker-compose run -e EDITOR="vim" web rails credentials:edit
```

```yaml
# ~~~
rds:
  host: RDSのエンドポイント
  database: RDSの「データベースの名前」
  username: RDSの「マスターユーザの名前」
  password: RDSの「マスターパスワード」
# ~~~
```

エンドポイントはAWSコンソールの【Amazon RDSダッシュボード】から【データベース】メニューにいき、対象の【DBインスタンス】を選択した先の【接続とセキュリティ】メニューの表示されている【エンドポイント】の値を設定します。

次にcredentialsの設定値を`config/database.yml`で読み取ります。

```yml:config/database.yml
# ~~~
default: &default
  adapter: postgresql
  encoding: unicode
  host: db
  username: postgres
  password:
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

production:
  <<: *default
  host: <%= Rails.application.credentials.rds[:host] %>
  database: <%= Rails.application.credentials.rds[:database] %>
  username: <%= Rails.application.credentials.rds[:username] %>
  password: <%= Rails.application.credentials.rds[:password] %>
# ~~~
```

# 2. EC2インスタンスの作成

## 2-1. EC2インスタンスを作成する
次に、AWSコンソールでEC2ダッシュボードを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/068fab7c-777d-dd4e-3c91-936d00626553.png)
ここで、【インスタンスの作成】を選択すると、インスタンス作成のフローに入ります。

### 手順１：AWSマシンイメージ（AMI）
AMIは無料枠のものを選択します。EC2の無料枠は750時間/月が1年間です。つまり1インスタンスなら１ヶ月起動しっぱなしでもOKです。
【Amazon Linux 2 AMI (HVM), SSD Volume Type】を選択していきます。

### 手順２：インスタンスタイプの選択
インスタンスタイプは無料枠になるものは１つしかないので問答無用で【t2.micro】を選択し、【次の手順：インスタンスの詳細の設定】を選択してください。

### 手順３：インスタンスの詳細の設定
各種設定をしていきます。ほぼデフォルトの設定でOKです。設定が完了したら【次の手順：ストレージの追加】を選択します。

|項目|値|
|:----------|:----------|
|インスタンス数|１|
|購入のオプション|チェックしない|
|ネットワーク|デフォルトのVPC|
|サブネット|優先順位なし（アベイラビリティゾーンのデフォルト）|
|自動割り当てパブリックIP|サブネット設定を使用（有効）|
|配置グループ|チェックしない|
|キャパシティーの予約|なし|
|IAMロール|なし|
|シャットダウン動作|停止|
|削除保護の有効化|チェックしない|
|モニタリング|チェックしない|
|テナンシー|共有 - 共有ハードウェアインスタンスの実行|
|Elastic Inference|チェックしない|
|T2/T3無制限|チェックしない|

### 手順４：ストレージの追加
ここは特に設定変更不要です。【次の手順：タグの追加】を選択します。

### 手順５：タグの追加
ここも特にそのままでいいです。【次の手順：セキュリティグループの設定】を選択します。

### 手順６：セキュリティグループの設定
以下の設定のセキュリティグループを作ります。新しいセキュリティグループを作成してもいいですし、既存のセキュリティグループを設定変更してもいいです。設定が完了したら【確認と作成】を選択します。

|タイプ|プロトコル|ポート範囲|ソース|
|:------|:------|:------|:------|
|HTTP|TCP|80|0.0.0.0/0|
|SSH|TCP|22|マイIP|

### 手順７：インスタンス作成の確認
設定を確認して【起動】を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/9b505831-5b2c-f275-c956-24343320dc35.png)
キーペアに関するポップアップが表示されるので、【新しいキーペアの作成】を選択し、【キーペア名】にアプリ名などを入力します。キーペアはEC2にSSHするときに利用するので【キーペアのダウンロード】を選択してローカルにダウンロードしておきます。
そこまでできたら【インスタンスの作成】を選択します。

作成が完了すると【EC2ダッシュボード】の【インスタンス】メニューにrunningステータスのインスタンスが追加されています。
![スクリーンショット 2019-05-12 20.28.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/c3819bb3-60b0-5b02-6e09-f70181a9ca55.png)

## 2-2. EC2からRDSへのインバウンドを許可する
RDSのセキュリティグループのインバウンドの設定に以下を追加します。

|タイプ|プロトコル|ポート範囲|ソース|
|:---|:---|:---|:---|
|PostgreSQL|TCP|5432|EC2のセキュリティグループのグループID|

## 2-3. Elastic IPを設定する
上で作成したEC2インスタンスにSSHするためにEIPを紐付けます。

### Elastic IPを割り当てる
【EC2ダッシュボード】の【Elastic IP】メニューを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/6e744b75-3f51-1183-af2c-98e5c3225b9d.png)

【新しいアドレスの割り当て】を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/10f4739f-ba61-9621-f772-9fc21e118a4b.png)

【割り当て】を選択。次のページでElastic IPが割り当てられますので、【閉じる】を選択して【Elastic IP】メニューに戻ります。


### Elastic IPをEC2に関連づける
![スクリーンショット 2019-05-12 20.41.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/8089f5a5-3a77-56b2-92b9-dd7877938d90.png)
【Elastic IP】メニューにElastic IPが追加されているので、選択し、【アクション】から【アドレスの関連付け】を選択します。

【アドレスの関連付け】ページに遷移するので、以下の設定をして【関連付け】を選択します。

|項目|値|
|:---|:---|
|リソースタイプ|インスタンス|
|インスタンス|先ほど作成したインスタンス|
|プライベートIP|多分1つしかないのでそれを選択|
|再関連付け|チェックなしでOK|

これで先ほど作成したEC2にElastic IPが関連づけられた状態になりました。
これでEC2にSSHすることができるようになりましたので、EC2にアクセスして設定をしていきます。

## 2-4. EC2の設定をする
### ローカル環境のSSH設定
まずはEC2にSSHするためのローカル環境の設定をしていきます。
EC2作成時にキーペアをダウンロードしていますので、それを使ってEC2にSSHします。

```
$ mkdir ~/.ssh
$ mv ~/Downloads/myapp.pem ~/.ssh/
$ chmod 600 ~/.ssh/myapp.pem
$ ssh -i ~/.ssh/myapp.pem ec2-user@xxx.xxx.xxx.xxx
```

xxx.xxx.xxx.xxxの部分にはEC2のEIPを入れてください。EIPは【EC2ダッシュボード】の【インスタンス】メニューで対象のインスタンスを選択すると出てくる【説明】メニューに記載されている【IPv4パブリックIP】の値です。
また、`ec2-user`はAWS linuxのデフォルトユーザーです。

初回ssh時は、「本当にsshするの？」みたいなことを聞かれますが「yes」と答えましょう。
また、「yum updateしろ」とも言われると思うのでしときます。

```
[ec2-user@ip-xxx-xxx-xxx-xxx ~]$ sudo yum update -y
```

### 新しいユーザーを作成する
ec2-userは世界の誰もが知っているユーザーなのでセキュリティ的にあまりよろしくないです。
ということで新しいユーザーを作成してそちらで作業をするようにします。ここでは「`myuser`」というユーザーを作る前提でコマンドを入力していきます。

```
[ec2-user@xxx.xxx.xxx.xxx ~]$ sudo adduser myuser #ユーザー作成
[ec2-user@xxx.xxx.xxx.xxx ~]$ sudo passwd myuser #パスワード変更
（パスワードを入力）x2
[ec2-user@xxx.xxx.xxx.xxx ~]$ sudo visudo
```
最後の`sudo visudo`コマンドで`vi`が立ち上がります。ここで`myuser`でもsudoが使えるように設定します。

```vim
root   ALL=(ALL) ALL
myuser ALL=(ALL) ALL
```
１行目が書かれている箇所があるはずなので、その下の行に２行目を追加します。これで`myuser`でも`sudo`コマンドが使えるようになりました。

最後に新しく作成したユーザーでもpemでSSHできるように以下のコマンドを入力します。

```
[ec2-user@xxx.xxx.xxx.xxx ~]$ sudo rsync -a ~/.ssh/authorized_keys ~myuser/.ssh/
[ec2-user@xxx.xxx.xxx.xxx ~]$ sudo chown -R myuser:myuser ~myuser/.ssh
[ec2-user@xxx.xxx.xxx.xxx ~]$ sudo chmod -R go-rwx ~myuser/.ssh
```

ここまでできたら一度ログアウトして、`myuser`でSSHできることを確認します。

```
[ec2-user@xxx.xxx.xxx.xxx ~]$ exit
$ ssh -i ~/.ssh/myapp.pem myuser@xxx.xxx.xxx.xxx
```

### EC2ユーザーを削除
ここまでで`myuser`でEC2の操作ができるようになっているので`ec2-user`を削除します。

```
[myuser@xxx.xxx.xxx.xxx ~]$ sudo userdel ec2-user
[myuser@xxx.xxx.xxx.xxx ~]$ sudo rm -rf /home/ec2-user/
```

## 2-5. Docker環境を整える
続いてEC2にDockerとdocker-composeをインストールしていきます。

### Dockerをインストール
```
[myuser@xxx.xxx.xxx.xxx ~]$ sudo yum install -y docker
[myuser@xxx.xxx.xxx.xxx ~]$ sudo service docker start #Dockerを起動
[myuser@xxx.xxx.xxx.xxx ~]$ sudo usermod -G docker myuser #dockerコマンドを権限なしで利用できるようにする
[myuser@xxx.xxx.xxx.xxx ~]$ exit
$ ssh -i ~/.ssh/myapp.pem myuser@xxx.xxx.xxx.xxx #再ログイン
[myuser@xxx.xxx.xxx.xxx ~]$ docker info
Containers: 0
 Running: 0
 Paused: 0
 Stopped: 0
Images: 0
・・・
# こんな感じの表示が出ればOK!
[myuser@xxx.xxx.xxx.xxx ~]$ sudo chkconfig docker on #EC2起動時にDockerを自動で立ち上げる
```

### docker-composeをインストール
docker-composeのインストールは「[Install Docker Compose | Docker Documentation](https://docs.docker.com/compose/install/)」を参照です。

```
[myuser@xxx.xxx.xxx.xxx ~]$ sudo curl -L "https://github.com/docker/compose/releases/download/1.24.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
[myuser@xxx.xxx.xxx.xxx ~]$ sudo chmod +x /usr/local/bin/docker-compose
[myuser@xxx.xxx.xxx.xxx ~]$ docker-compose -v
docker-compose version 1.24.0, build 0aa59064 #こんな表示が出ればOK!
```

## 2-6. GitlabをEC2上でcloneする
**2-6/2-7はEC2のCPUが高騰することがあるので「[Ruby on Rails on Docker on AWSのbuildでCPUが高騰するもんだからbuild済みのimageをpullすることにしました。 - Qiita](https://qiita.com/at-946/items/f0ec23483400eeebfdd9)」の方法を参考にしていただいた方がいいかもしれません。** - 2019.06.03更新

ローカルにcloneするやり方といっしょです。「[Gitlab で リポジトリをローカルにクローンする - Qiita](https://qiita.com/Taylor-U/items/0aba74d498281ffb0a7b)」の記事が参考になりました。
EC2でのコマンドをつらつら書いておきます。

```
[myuser@xxx.xxx.xxx.xxx ~]$ sudo yum install -y git #gitをインストール
[myuser@xxx.xxx.xxx.xxx ~]$ cd .ssh
[myuser@xxx.xxx.xxx.xxx ~/.ssh]$ ssh-keygen -t rsa -f gitlab
[myuser@xxx.xxx.xxx.xxx ~/.ssh]$ chmod 600 gitlab gitlab.pub
[myuser@xxx.xxx.xxx.xxx ~/.ssh]$ cat gitlab.pub #これをGitlabに登録

# Gitlab登録

[myuser@xxx.xxx.xxx.xxx ~/.ssh]$ vim config
```

```:.ssh/config
Host gitlab.com
  User git
  HostName gitlab.com
  IdentityFile ~/.ssh/gitlab
```

```
[myuser@xxx.xxx.xxx.xxx ~/.ssh]$ cd
[myuser@xxx.xxx.xxx.xxx ~]$ git clone [Gitlabからコピペしたパス（git@gitlab.com:xxxxx/myapp.git）]
```

## 2-7. コンテナ起動
GitlabにはRailsのcredentialsを解読するのに必要な`config/master.key`をpushしていないと思うので、これをローカルからEC2に直接渡してからbuild/upをしていきます。

```
[myuser@xxx.xxx.xxx.xxx ~]$ exit
$ scp -i ~/.ssh/myapp.pem ~/myapp/config/master.key myuser@xxx.xxx.xxx.xxx:./myapp/config/
[myuser@xxx.xxx.xxx.xxx ~]$ cd myapp
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ docker-compose build
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ docker-compose run web rails db:create
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ docker-compose run web rails db:migrate
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ docker-compose run web rails assets:precompile
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ mkdir tmp/sockets
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ touch tmp/sockets/puma.sock
[myuser@xxx.xxx.xxx.xxx ~/myapp]$ docker-compose up
```

これで`http://xxx.xxx.xxx.xxx`にアクセスすれば、ひとまずRailsアプリが表示されているはずです。

# 3. ALBの作成
サクッとALB作ります。本当はロードバランシングや冗長構成のために使うべきかとは思いますが、今回はACMを適用するためだけに利用します。

【EC2ダッシュボード】の【ロードバランサー】メニューを開き、【ロードバランサーの作成】を選択して作成フローに進みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/b472588c-ee97-3179-6c93-a31f7c31ef11.png)

### ロードバランサーの種類の選択
【Application Load Balancer】を選びます。

### 手順１：ロードバランサーの設定
以下の通りに設定していきます。

```
# 基本的な設定
名前：おまかせ
スキーム：インターネット向け
IPアドレスタイプ：ipv4

# リスナー
HTTP : 80
HTTPS : 443

# アベイラビリティーゾーン
VPC：デフォルト
アベイラビリティーゾーン：少なくとも2つを選択（EC2が存在するところ）
```

### 手順２：セキュリティ設定の構成
この時点では設定できる項目がないので【次の手順：セキュリティグループの設定】を選択します。

### 手順３：セキュリティグループの設定
ALB用の新しいセキュリティグループを作成します。以下の設定を入力したら【次の手順：ルーティングの設定】を選択します。

|タイプ|プロトコル|ポート範囲|ソース|
|:---|:---|:---|:---|
|HTTP|TCP|80|0.0.0.0/0|

### 手順４：ルーティングの設定
ここではターゲットグループを作成します。ターゲットグループはALBがロードバランシングする対象（EC2など）のグループで、ALBにリクエストがくるとそのターゲットの中からいい感じに振り分けをしてくれます。今回は1インスタンスしかないですが...

ここでは以下のように入力して、【次の手順：ターゲットの登録】を選択していきます。

ターゲットグループ

|項目|設定値|
|:---|:---|
|ターゲットグループ|新しいターゲットグループ|
|名前|おまかせ|
|ターゲットの種類|インスタンス|
|プロトコル|HTTP|
|ポート|80|

ヘルスチェック

|項目|設定値|
|:-:|:-:|
|プロトコル|HTTP|
|パス|/|

### 手順５：ターゲットの登録
ここで手順４で作成したターゲットグループにEC2を入れていきます。
【インスタンス】の方に作成したインスタンスIDがあるかと思いますので、そちらにチェックを入れて【登録済みに追加（ポート80）】を選択します。
そうすると上の【登録済みのターゲット】の方にもそのインスタンスの情報が表示されるようになります。
これでターゲットの登録は完了なので【次の手順：確認】を選択します。

### 手順６：確認
最終チェックをして【作成】を選択します。すこし待つと「ロードバランサーを正常に作成しました」と作成完了のメッセージが表示されますので、【閉じる】を選択して【ロードバランサーメニュー】の画面に戻ります。

## ALB経由でサイトにアクセスできることを確認する
先ほど作成したALBはすでにDNS（Domain Name Service）に登録されている状態になるので、先ほどまでEC2のIPアドレスを直接ブラウザに入力してサイトを表示させていましたが、ALBのDNS名でもアクセスできるようになっています。（DNSの登録が完了するまでに少しだけ時間がかかるかもしれません）

ALBのDNS名は【ロードバランサーメニュー】でALBを選択して、ページ下の【説明】タグの中の【DNS名】がそれです。（xxxxxxx.elb.amazonaws.comみたいなやつです。）
これをそのままブラウザのURLバーにコピペすれば「http://xxx.xxx.xxx.xxx」でアクセスしていたときと同じ結果が得られるはずです。

# 4. ドメインの適用（Freenom）
今のままでは思い通りのドメインではないと思いますので、サービスにあったドメインでアクセスできるようにしていきます。

## 4-1. ドメインを取得する
ドメインは無料ドメインのFreenomを利用します。「[Freenom - 誰でも利用できる名前](http://www.freenom.com/ja/index.html)」
「.com」とか「.co.jp」とかはお名前.comやAWSでも買えるんですがお金かかっちゃうので使わないということで。

ドメインの取得方法はいくつか記事があるのでそちらを参考に。「[無料のドメインを取得する - Qiita](https://qiita.com/teekay/items/135dc67e39f24997019e)」

「Forward this domain」と「Use DNS」を選択する箇所が出てきますが、「Forward this domain」を選択して先ほどのALBのDNS名を入力しておくとすぐに使えるようになります。あとPeriodは12ヶ月にしておきましょう。
![スクリーンショット 2019-05-14 23.43.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/3eb932c7-779c-88cf-b1a3-0830f0b5376c.png)

0円購入が完了するとすでにそのドメインにアクセスするとALBのDNS名にリダイレクトされるようになっているはずです。
ただ、例えば「myapp.tk」というドメインを買ったとしたら、「www.myapp.tk」などでサイトを公開したいので、DNSの登録をしていきます。

## 4-2. DNS登録
Freenomのサイトのヘッダーのメニューから「Services > My Domain」を選択します。
そこに先ほど0円購入したドメインが表示されていますので、【Manage Domain】を選択し、次のページで【Manage Freenom DNS】を選択して【DNS MANAGEMENT】ページに移動していきます。

最初はまだ何も登録されていないと思いますので、【Edit Nameservers】を選択してDNSサーバーを登録します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/e09c8ed2-02c5-cac6-e9d6-9ec41dcdae29.png)
次のページは【Use default nameservers】でいいです。

nameserversの設定が終わったらもう一度【DNS MANAGEMENT】ページに移動して、以下のレコードを登録していきます。

|Name|Type|TTL|Target|
|:--|:--|:--|:--|
|WWW|CNAME|3600|ALBのDNS名（"http://"は不要）|

【Name】は「www」以外でもOKです。例えば「app」なんてのも最近多い気がします。
ただし、未入力はダメです。ACMを登録するときにRoute53以外を利用する場合はドメインのみを指定できないので必ず「www.myapp.tk」のような形にする必要があります。

ここまで完了したら「`http://www.myapp.tk/`」にアクセスすることでそのURLのままサイトにアクセスすることができるようになっています。

# 5. HTTPS化
最後はHTTPS化です。最近のChromeだとHTTPS対応していないと「保護されていない通信」と表示されてしまいますし、対応しておいた方が無難だと思います。

## 5-1. ACMでSSL証明書を発行する

### 証明書のリクエスト
AWSコンソールのメニューで【Certificate Manager】へアクセスし、【証明書のプロビジョニング】の【今すぐ始める】を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254216/2199b66f-08dd-6ba9-18eb-096e6afd6ef4.png)

次のページで【パブリック証明書のリクエスト】を選択して、【証明書のリクエスト】を実行します。
 
### ステップ１：ドメイン名の追加
【ドメイン名】のところにFreenomで登録したドメインを入力していきます。今回の例だと、「www.myapp.tk」です。入力できたら【次へ】を選択します。

### ステップ２：検証方法の選択
ここでは【DNSの検証】を選択して【確認】をクリックします。

### ステップ３：確認とリクエスト
内容を確認したら【確定とリクエスト】を選択します。

### ステップ４：検証
さて、このページでDNSに以下を登録するように指示が出ます。

|名前|タイプ|値|
|:-:|:-:|:-:|
|`_xxxxxxxxxx.www.myapp.tk.`|CNAME|_xxxxxxxxxx.acm-validations.aws.|

これをFreenomの【DNS MANAGEMENT】ページでDNSにレコード追加してあげます。
やや編集が必要なので注意です。

|Name|Type|TTL|Target|
|:-:|:-:|:-:|:-:|
|_xxxxxxxxxx.WWW|CNAME|3600|_xxxxxxxxxx.acm-validations.aws|

注意する点は、「NAMEの".myapp.tk."が不要」なことと「Targetの最後の"."が不要」なことです。

ここまで済んだら【続行】を選択します。

ここまで済んだら発行が済むのを待つのみです。【状況】が【発行済み】になるまでしばらくかかります（10分くらい？）

## 5-2. SSL証明書をALBに適用する
AWSコンソールから【EC2ダッシュボード > ロードバランサー】に遷移します。
対象のALBを選択して【リスナー】タグから【リスナーの追加】を選択します。

### HTTPSリスナーの追加
【プロトコル：ポート】として【HTTPS：443】を選択します。するといくつか項目が追加されます。

【デフォルトアクション】は【アクションの追加】から【転送先...】を選択して、転送先としてALB作成時に作ったターゲットグループを指定します。
【セキュリティポリシー】はノータッチでOKです。
【デフォルトのSSL証明書】には先ほど作成したACMの証明書を選択してください。

ここまで設定が完了したら、【保存】を選択してください。

### HTTPリスナーの削除
HTTPSをリッスンできるようにするのでHTTPリスナーは不要になります。ので【EC2ダッシュボード > ロードバランサー】メニューの【リスナー】タブでHTTPリスナーを選択して削除してください。

### ALB用のセキュリティグループの更新
ALB用のセキュリティグループが現状、80ポートをallow・443ポートはdenyの状態になっているので更新します。
【EC2ダッシュボード > セキュリティグループ】メニューで該当のセキュリティグループを選択して【インバウンド】タブを見てみてください。

|タイプ|プロトコル|ポート範囲|ソース|
|:--|:--|:--|:--|
|HTTP|TCP|80|0.0.0.0/0|

となっているはずなので、

|タイプ|プロトコル|ポート範囲|ソース|
|:--|:--|:--|:--|
|HTTPS|TCP|443|0.0.0.0/0|

に更新します。

これで「`https://www.myapp.tk/`」でサイトにアクセスできるようになります。
一方で「`http://www.myapp.tk/`」のアクセスはできなくなっていることを確認してください。

### EC2のセキュリティグループの見直し
今のままでは実は「`http://xxx.xxx.xxx.xxx`」ではアクセスができてしまいます。
これはかっこ悪いのでEC2のセキュリティグループを見直します。

今、EC2に適用しているセキュリティグループは

|タイプ|プロトコル|ポート範囲|ソース|
|:--|:--|:--|:--|
|HTTP|TCP|80|0.0.0.0/0|
|SSH|TCP|22|マイIP|

となっているはずなので、

|タイプ|プロトコル|ポート範囲|ソース|
|:--|:--|:--|:--|
|HTTP|TCP|80|ALBのセキュリティグループのグループID|
|SSH|TCP|22|マイIP|

と変更してあげてください。
こうすることでALBからのHTTPアクセスのみを受信できるようになります。

以上で完成です！！！！

# おわりに
長くなってすみません！（笑）

もちろん方法はこれだけではないので、あくまで一例という形で考えていただければと思います！

毎回結構つまずくところなのでまとめられて個人的によかった。