January 17, 2018

Ruby on Rails 5.1 on AWS Elastic Beanstalk 事始め

今回つくるもの

AWS の Elastic Beanstalk を利用して、Rails 5.1 アプリケーションを EC2 + RDS の構成にデプロイする環境を作ります。

構成図

環境

作業環境は macOS Sierra (10.12) です。以下のコマンドが実行できる状態を前提とします。

$ eb --version
EB CLI 3.12.1 (Python 3.6.3)
$ rails -v
Rails 5.1.4

eb コマンドが実行できない場合は Elastic Beanstalk コマンドラインインターフェイス(EB CLI)のインストール - AWS Elastic Beanstalk を参考にしてください。rails コマンドは Ruby および Bundler をインストール後、 $ gem install rails で入ります。

方針・前提

  • Database は MySQL を採用
  • Application Server は Puma を採用
  • 極力 AWS Console をブラウザで開かない(操作結果の確認にのみ利用)
  • 範囲は Rails アプリの新規作成から Scaffold した画面を本番環境で確認するまで
  • 独自ドメインの適用、HTTPS 化は本稿では扱わない

手順

1. Rails アプリの作成

Git で commit していない差分は Elastic Beanstalk で上手にデプロイされません。細かく commit していきます。

$ rails new eb-rails-mysql -d mysql
$ cd eb-rails-mysql
$ git add .
$ git commit -m 'rails new'

2. Puma の設定

$ vi config/puma.rb

以下を Puma 設定ファイルの末尾に追記します。

# Configurations for Elastic Beanstalk
if Rails.env.production?
  bind "unix:///var/run/puma/my_app.sock"
  pidfile "/var/run/puma/my_app.sock"
end
$ git commit -am 'updated puma.rb for Elastic Beanstalk'

3. Database の設定

$ vi config/database.yml

今回は Elastic Beanstalk 経由で RDS インスタンスを起動します。RDS インスタンスを起動すると、環境変数に RDS_DB_NAME 等 Database への接続に必要な情報が設定されるので、 production 環境の DB 接続設定を以下の通り編集します。

production:
  <<: *default
  database: <%= ENV['RDS_DB_NAME'] %>
  username: <%= ENV['RDS_USERNAME'] %>
  password: <%= ENV['RDS_PASSWORD'] %>
  host: <%= ENV['RDS_HOSTNAME'] %>
  port: <%= ENV['RDS_PORT'] %>
$ git commit -am 'updated database.yml for Elastic Beanstalk'

4. Elastic Beanstalk Application の作成

Elastic Beanstalk には複数のアプリケーションを作成することができ、それぞれのアプリケーションの下位概念として Environment (環境) を定義することが可能です。ここでは対話式にアプリケーションの作成を行える $ eb init コマンドを利用します。

$ eb init

はじめにリージョンの選択を行います。東京リージョンを選びます。

Select a default region
1) us-east-1 : US East (N. Virginia)
(中略)
9) ap-northeast-1 : Asia Pacific (Tokyo)
(後略)
(default is 3): 9

Application Name を設定します。デフォルトでは $ rails new した時のプロジェクト名が使われます。

Enter Application Name
(default is "eb-rails-mysql"): eb-rails-mysql
Application eb-rails-mysql has been created.

$ eb init コマンドを実行したディレクトリの中身に応じて、動作プラットフォームを提案してくれます。ここでは Ruby 2.4 + Puma の組合せを選択します。

It appears you are using Ruby. Is this correct?
(Y/n): Y

Select a platform version.
1) Ruby 2.4 (Puma)
(中略)
10) Ruby 2.0 (Passenger Standalone)
11) Ruby 1.9.3
(default is 1): 1

AWS CodeCommit の宣伝がありますが、無視します。

Note: Elastic Beanstalk now supports AWS CodeCommit; a fully-managed source control service. To learn more, see Docs: https://aws.amazon.com/codecommit/
Do you wish to continue with CodeCommit? (y/N) (default is n): N

Elastic Beanstalk 経由で立ち上げた EC2 インスタンスへの SSH アクセスを有効にしたいかどうか聞かれます。何かと便利なので有効にしておきましょう。有効にするとどのキーペアを使うか聞かれます。このタイミングで新たにキーペアを生成することも出来ますが、私は既存のものを選びました。

Do you want to set up SSH for your instances?
(Y/n): Y

Select a keypair.
1) ******
2) ******
3) [ Create new KeyPair ]
(default is 2): 2
$ git add .
$ git commit -m 'eb init'

AWS Console で Application の作成結果を確認しましょう。AWS Console は $ eb console コマンドで簡単に開くことが出来ます。

Elastic Beanstalk Console

ここまで問題なく進んだら、Enviconment (環境) の作成に進みます。

5. Elastic Beanstalk Environment の作成

Application の作成は $ eb init コマンドで行いましたが、Environment の作成は $ eb create コマンドで行います。RDS のインスタンスタイプ等は後々 Console を開いて設定可能ですが、面倒なのでコマンド一発でまとめて設定してしまいます。

  • Environment Name として eb-rails-mysql-development を指定します。
  • EC2 インスタンスタイプに t2.micro を指定します。
  • データベースエンジンに MySQL を指定します。
    • RDS のインスタンスタイプは db.t2.micro を指定します。
    • db.t2.micro は現状選択できる最安の RDS インスタンス (0.026USD/時間 = 0.624USD/日 = 18.72USD/30日) です。
    • MySQL のバージョンとして 5.7.19 を指定します。
  • 環境変数として SECRET_KEY_BASE を指定し、値を rake secret により生成します。
    • これがないと Rails アプリケーションが起動しません。
  • CNAME として eb-rails-mysql-development を指定します。この値は検証用のドメインの一部になります。
$ eb create eb-rails-mysql-development \
--instance_type t2.micro \
--database.engine mysql \
--database.instance db.t2.micro \
--database.version 5.7.19 \
--envvars SECRET_KEY_BASE=$(rake secret) \
--cname eb-rails-mysql-development

このコマンドを実行すると、対話的に RDS の username, password の設定を求められるので対応します。その後、環境が立上がるまで数分〜十数分かかるので待ちます。特に RDS インスタンスの立ち上げには 10 分程度かかることもありますが、気長に待ちましょう。

6. Environment の確認

INFO: Successfully launched environment: eb-rails-mysql-development

ログに以上のような表示が出たら、Environment の立上げは完了です。以下のコマンドを打ち込むと、ブラウザの中で Environment が立ち上がります。

$ eb open

The page you were looking for doesn't exist.

見慣れた 404 画面が出てきました。Rails のアプリケーションは全く作成していないので当たり前ですね。

7. Scaffold & Deploy

$ rails g scaffold article title body:text --no-assets --no-jbuilder --no-helper --no-fixture

routes.rb を編集し、Scaffold によって生成される articles#index:root に設定します。

# config/routes.rb

Rails.application.routes.draw do
  root 'articles#index'
  resources :articles
end

rails s で動作を一通り確認したら、Git にコミットした上で Elastic Beanstalk 上にデプロイします。このように、手元環境で開発 → Git コミット → Elastic Beanstalk へのデプロイ、というのが基本的な開発の流れになります。Elastic Beanstalk へのデプロイには eb deploy コマンドを使います。

$ git add .
$ git commit -m 'scaffold articles'
$ eb deploy
Creating application version archive "app-****-******_******".
Uploading eb-rails-mysql/app-****-******_******.zip to S3. This may take a while.
Upload Complete.
INFO: Environment update is starting.
INFO: Deploying new version to instance(s).
INFO: New application version was deployed to running EC2 instances.
INFO: Environment update completed successfully.

eb open コマンドでブラウザを開くと、変更が反映されたアプリが確認できます。

Scaffold Result

Copyright alea12 2018