🌿

AWS Elastic Beanstalk で独自ドメインとSSL対応した Rails アプリを公開するまで

2021/07/17に公開

TL;DR

AWS Elastic Beanstalk とは

  • https://aws.amazon.com/jp/elasticbeanstalk/
  • AWS の aPaaS のひとつ
  • ロードバランサー(CLB,ALB,NLB)、EC2、RDS、ヘルスチェックやログ収集、アプリケーションデプロイなどAWSでアプリケーション公開に必要なフルセットを提供してくれる
    • ドメイン管理の Route 53 や AWS Certificate Manager でのSSL証明書発行は別途独自で用意する必要あり
  • heroku の AWS 版ぐらいの気持ちで取り組んだが、いかにherokuが親切な作りになっているかを思い知りました……w

eb コマンドを使えるようにするまで

1. IAMユーザーの作成

  • AWSElasticBeanstalkFullAccess もしくは AWSElasticBeanstalkFullAccess が内包されたポリシーを持つグループに所属したIAMユーザーを作成します

2. awscli の準備, アクセスキーの設定

  • Mac なら homebrew から $ brew install awscli でイケます

  • インストールしたら $ aws configure コマンドでアクセスキーなどの設定をしておきます。

    • AWS Access Key, AWS Secret Access Key は AWS マネジメントコンソール(AWSの管理Webページ) に作成した IAM ユーザでログインし、右上メニューの名前部分をクリックして出てくる「マイセキュリティ資格情報」から確認することができます
  • brewでAWS CLIのインストール | Qiita

3. awsebcli の準備

  • Mac なら homebrew から $ brew install awsebcli でイケます

Elastic Beanstalk アプリケーションを作成する

  • Elastic Beanstalk アプリケーションは AWS マネジメントコンソール(AWSの管理Webページ) からWeb上で作成もできますが、その後のデプロイまでの手順がクッソややこしくなるので素直に awsebclieb コマンドで準備進めた方が良さそうというかそうした

eb init で Elastic Beanstalk の初期設定を行う

# デプロイしたいアプリケーションのrootディレクトリで eb init すること
$ eb init

以降は対話形式でアプリケーションの設定を行なっていくので
コマンドラインできかれたことに応じて進めていきましょう。

対話形式が終わった時点で .elasticbeanstalk ディレクトリが作成されていると思います。
また、その時点で AWS マネジメントコンソール(AWSの管理Webページ) から Elastic Beanstalk を開くと「アプリケーションを作成しましょう!」という表示になっているはずです。
事項の eb create へ進みましょう。

以下 対話形式で詰まったポイント

It appears you are using Docker. Is this correct?

ローカルでの開発をDockerで行っていると気を利かせて
It appears you are using Docker. Is this correct?(Y/n):
きいてきてくれるんですが、ここは強い気持ちで n と回答し
その後の使用言語選択で Ruby アプリケーションとして進める方が
Elastic Beanstalk の Ruby デプロイ関連が使えるのでいい気がします。

(もちろん、Elastic Beanstalk の Docker サポートでアプリケーションを作りたいのならそれでもOKとは思います)

Do you wish to continue with CodeCommit?

これは No にしました(その後別に困ってない)

Do you want to set up SSH for your instances?

のちのち Elastic Beanstalk の EC2 に SSH したいのでここは yes にしておきます。

eb create で Elastic Beanstalk でアプリケーションを作成する

今回は最初に $ eb create してエラーを発生させた状態でデプロイした後に
エラーを解消していく、という手法で構築するのですが、
構築に慣れてくれば $ eb create にオプションをつけて実行することで
$ eb create と同時に RDS も作って環境変数も入っててという状態にする方が効率は良さそう。
※今回はできてない

# 引き続きデプロイしたいアプリケーションのrootディレクトリで eb create すること
$ eb create

Select a load balancer type は 2) application でいいでしょう。
eb create が完了すると、
AWS マネジメントコンソール(AWSの管理Webページ) から Elastic Beanstalk アプリケーションが確認できるようになっており、ヘルスでNGになっているはずです。
そのほかの準備を進めていきましょう

デプロイ設定の変更

初期設定では Elastic Beanstalk アプリケーションはデプロイに成功して当然、NGになるなら各種設定はキャンセルする様な設定になっているので、
もろもろ試行錯誤しながらデプロイ成功まで持っていくのに適していません
(というか環境変数の設定すら拒否される)
そのため、AWS マネジメントコンソール(AWSの管理Webページ) から Elastic Beanstalk アプリケーションを開き、「設定」から各種設定をいじっていきます。

ただし、この手順は正確ではない気がするので
あくまで 私がデプロイ成功までもっていった時の手法 程度に斜め読みしてもらえればと思います。

ローリング更新とデプロイ

  • デプロイメントポリシー
    • 1回にすべて に変更
  • 設定の更新
    • ローリング更新のタイプ
      • 無効 に変更
  • デプロイの設定
    • ヘルスチェックを無視
      • True に変更



モニタリング

  • ヘルスレポート
    • ベーシック に変更

RDS を作成する

AWS マネジメントコンソール(AWSの管理Webページ) から Elastic Beanstalk アプリケーションを開き、「設定」から RDS を作成します。
初期設定ユーザーとパスワードの設定が行えるので実施します。
RDS の作成が完了すると、ホスト名、ポート、データベース名(おそらく ebdb) が確認できるはずです。

環境変数を設定する

例えば config/database.yml をこうしたとして

config/database.yml
default: &default
  adapter: postgresql
  encoding: unicode
・・・(中略)
production:
  <<: *default
  database: <%= ENV['RDS_DB_NAME'] %>
  username: <%= ENV['RDS_USERNAME'] %>
  password: <%= ENV['RDS_PASSWORD'] %>
  host: <%= ENV['RDS_HOSTNAME'] %>
  port: <%= ENV['RDS_PORT'] %>

設定すべき環境変数は以下です

  • 上記RDSの作成でわかっているはずの情報
    • RDS_DB_NAME
    • RDS_USERNAME
    • RDS_PASSWORD
    • RDS_HOSTNAME
    • RDS_PORT
  • production での migration 実施などに必要
  • ./public 配下を puma から配信する場合、必要

環境変数の設定は AWS マネジメントコンソール(AWSの管理Webページ) から Elastic Beanstalk アプリケーションを開き、「設定」から「ソフトウェアの変更」を開き、「環境プロパティ」から設定して「適用」することでも追加できますし、$ eb setenv RDS_DB_NAME=ebdb コマンドでも設定できます。
お好きな方で。

上記 デプロイ設定の変更 が完了していない場合、この環境変数の設定でハマりまくる可能性がありますがめげずに色々試してみてください。。。

設定が終わったら元々ある環境変数なども合わせてこんな感じになっているはずです。

デプロイする

ここまでの準備が済んだら、再度デプロイを行います。

# 引き続きデプロイしたいアプリケーションのrootディレクトリで eb create すること
$ eb deploy

Elastic Beanstalk の Ruby アプリケーションは eb deploy コマンドで
ファイルのアップロードと rails db:migrate が実施されます(環境変数の設定による、defaultでtrue)

デプロイが正常に完了したら、$ eb open コマンドでブラウザが開いてアクセスできるようになっているはずです。
デプロイが完了しない場合、

# ログ確認
$ eb logs

で migration に失敗しているなどエラーが確認できるので、
環境変数の見直しなど実施してもらえればと思います。

独自ドメインを設定する

ドメインの管理のために Route 53 に新規ホストゾーンを追加します。
ホストゾーンを追加することで NS レコードと SOAレコードが生成されます。

NS レコードをドメイン登録事業者側に設定してやる

今回は Google Domain を使っていたので
Google Domain の DNS レコード設定から NS レコードを設定してやります。
Google Domain の場合、NS レコード1つに対して複数のサーバーを設定する方法が分かりづらいのですが、画像にある矢印の「+」から設定値欄を追加してやることができました。
Route 53 で発行される NSレコードには 4サーバーあるはずなので、全て指定してやります。

Aレコードを作成し Elastic Beanstalk に紐付ける

Route 53 の設定から、Aレコードを作成します。
レコードの作成 からレコードタイプ A、
トラフィックのルーティング先は「エイリアス」をONにすれば
作成済みの Elastic Beanstalk アプリケーションが指定できるはずなので、指定します。

これで、独自ドメイン対応ができました。

SSL証明書を発行する

SSL 証明書を発行するために AWS Certificate Manager の設定を行います。
「証明書のプロビジョニング」「いますぐ始める」からドメインを指定して証明書作成を行います。

証明書の検証には「DNS検証」を指定すると、
すでに作成済みの Route 53 ドメインホストが存在する存在する場合自動的に Route 53 の設定に CNAME レコードを追記してくれます。
あとは少し待てばSSL証明書が「発行済み」のステータスになるはずです。

Route 53 に CNAME レコードが設定される

CNAME レコードが追加された結果、
最終的に、 Route 53 のレコード設定は以下のようになっているはずです。

Elastic Beanstalk のロードバランサで 443 を待ち受けるようにする

ドメインの設定、SSL証明書の発行が完了したなら
あとは Elastic Beanstalk のロードバランサで 443 を待ち受けるようにするだけです。

AWS マネジメントコンソール(AWSの管理Webページ) から Elastic Beanstalk アプリケーションを開き、「設定」から「ロードバランサー」を開き
「リスナーの追加」から port443 プロトコル HTTPS を指定すれば
先ほど設定したSSL証明書が出てくるはずなので、指定して「適用」で完了します。

完了したら https://~ でアクセスしてみましょう。いけるはずです。

今回できなかったこと

HTTP(port 80)リクエストを HTTPS(port 443)へ自動リダイレクトするルールの設定が
できませんでした。。。
おそらく、ロードバランサのルール設定でいけるはずなのですが
辿り着けませんでした。

.ebextensions 配下に設定を書いて $ eb deploy する方が簡単かもしれません。

以下など参考にチャレンジしてみてください。

今回は以上です。
正直、ここまで苦戦するとは思いませんでしたが誰かの役に立てれば幸いです。

Discussion