FIVETEESIXONE

Rails 4.2 を PostgreSQL を使って Elastic Beanstalk にセットアップする (1)


これまで Rails アプリケーションの公開は Heroku への楽ちんデプロイしかしたことがなかったので、AWS を使ってみることにしました。でもやっぱりサービスを自分で組み合わせて構築するのは大変そうだったので、結局、PaaS として使える Elastic Beanstalk を利用することにしました。

最終的には、ELB のロードバランシングと RDS のレプリケーションによる冗長化と、セッションストアに ElastiCache や DynamoDB を使った動作確認までしたいと思ってますが、とりあえずは普通に動かすとこまで。長いので何回かに分けて書きます。ちなみに Ruby のバージョンは 2.1.5 にしました。

Elastic Beanstalk CLI のインストール

Elastic Beanstalk は Web の管理コンソールから管理しますが、CLI も用意されています。しかし、AWS のドキュメントでも古いのから新しいのまで色々な情報が書いてあって、正直、いきなりここで何を使えばいいのかがわからず苦戦しました。結局、Homebrew からインストールできる Elastic Beanstalk 専用の CLI をインストールしましたが、これが正解なのかは分かりません。

$ brew update
$ brew install aws-elasticbeanstalk

これをインストールすると、eb という管理コマンドが使えるようになります。本体は Python スクリプトのようです。

Rails 4.2 アプリケーションの作成

いつもと同じように作ります。ただ、今回は PostgreSQL を使うことが決定しているので、最初から production 以外でも PostgreSQL を使うように構成します。

$ rails _4.2.0_ new rails-beanstalk -d postgresql

-d postgresql オプションによって、Gemfileconfig/database.yml が PostgreSQL 用に構成されます。

まずこの状態で git init しておきます。

$ cd rails-beanstalk 
$ git init
$ git add -A
$ git commit -m"Initial commit"

Elastic Beanstalk アプリケーションの作成

Elastic Beanstalk アプリケーションは eb init で作成します。1 回目の実行のときだけ、途中で、AWS に 接続するための IAM アクセスキー情報が必要になります。

$ eb init
Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-southeast-1 : Asia Pacific (Singapore)
7) ap-southeast-2 : Asia Pacific (Sydney)
8) ap-northeast-1 : Asia Pacific (Tokyo)
9) sa-east-1 : South America (Sao Paulo)
(default is 3): 8
#<= Tokyo を選択

You have not yet set up your credentials or your credentials are incorrect 
You must provide your credentials.
(aws-access-id): ***********
(aws-secret-key): **************************
#<= Access Key Id と Secret Access Key を入力

Enter Application Name
(default is "rails-beanstalk"):
#<= そのままエンター

Application rails-beanstalk has been created.

It appears you are using Ruby. Is this correct?
(y/n): y
#<= Yes

Select a platform version.
1) Ruby 2.1 (Puma)
2) Ruby 2.1 (Passenger Standalone)
3) Ruby 2.0 (Puma)
4) Ruby 2.0 (Passenger Standalone)
5) Ruby 1.9.3
(default is 1): 
#<= そのままエンター

Do you want to set up SSH for your instances?
(y/n): n
#<= とりあえず No

これで、Elastic Beanstalk アプリケーションが作成されます。Web のコンソール上でもアプリケーションができていることが確認できます。ただし、まだこの時点では Elastic Beanstalk を構成する EC2 のインスタンスなどは作成されていないので、課金はされないはずです (たぶん)。

また、これを実行すると Elastic Beanstalk 用のファイルを無視するように .gitignore が自動的に更新されますので、一旦コミットしておきます。

$ git commit -am"Update .gitignore"

アプリケーションに environment を設定する

Elastic Beanstalk では、1 つのアプリケーションに複数の environment を構成できます。開発用やステージング用、本番用などに使い分けられるということでしょう。ただ、今回は 1 つの environment しか作りません。

environment は eb create で作成します。が、CLI からだと作成時に何も設定ができないので、Web コンソールから作った方が良いのかもしれません。とりあえずここはこのまま CLI を使って、rails-beanstalk-env という environment を作成します。

$ eb create rails-beanstalk-env

これを実行すると、Elastic Beanstalk を構成する以下のサービスが自動的に構築されます。

  • environment 用のデータを格納するための S3 バケット
  • トラフィック分散のためのロードバランサー
  • トラフィックに対する Security Group
  • オートスケールのための CloudWatch ネットワーク監視アラーム

このように色々準備するので、かなり時間がかかります…

これを実行すると、おそらく、出力に以下のようなエラーが出ていると思います。

Command failed on instance. Return code: 1 Output: [CMD-Startup/StartupStage0/AppDeployPreHook/12_db_migration.sh] command failed with error code 1: /opt/elasticbeanstalk/hooks/appdeploy/pre/12_db_migration.sh

これは、PostgreSQL の準備ができていないので発生しているエラーです。DB の設定はこれから行っていくので、現時点ではスルーして OK です。詳しいエラー内容が見たければ、eb logs を実行するとログが確認できます。

また、上記したように、ここで EC2 インスタンスなどが起動するので、放置しているとそれらに対する課金が行われます。eb terminate を実行すれば、作成された EC2 インスタンスなどは削除されます。ただ、S3 バケットだけは自動では削除されません。

続きは次回にします。

おまけ

development 環境で Rails をローカル起動したいとき、rake db:migrate する前に以下を実行して DB を先に作っておかないとエラーになります。

$ rake db:create RAILS_ENV=development