AWS Elastic Beanstalk x Ruby on Rails で構築する

セットアップする環境

Ruby on Rails5
RDS (Mysql)
Puma
CloudFront
を用いて起動させる。

アプリケーション名は {app name} とする。

手順

RDS を起動

eb コマンドで、同時にRDS を起動させることも可能だが、アプリケーションの削除と同時に、RDSも消えてしまうため、別々に作成する。
マスターユーザー、マスターユーザーのパスワード、インスタンス名は、何でも良く、DBは作らなくて良い。

RDSを作るとき、新規で SecurityGroup を作成し、その名前は rds-launch-wizard に、インプットのソースに、自身を追加する。

f:id:unching-star:20161006082808p:plain

RDS で ユーザーの作成

権限を絞るため、Beanstalk から接続するためのユーザーを作成する。

GRANT ALTER, CREATE, DELETE, DROP, INDEX, SELECT, UPDATE, INSERT ON dbname_dayo.* TO username_dayo@'%' IDENTIFIED BY 'password_dayo';
Rails プロジェクトに設定を追加

1. 通常のRailsのセットアップを行う。

2. ENV を書く

環境構築時に変数として渡したい所は、ENV で指定する。

$ vi config/database.yml
...

production:
  <<: *default
  database: <%= ENV['RDS_DB_NAME'] %>
  username: <%= ENV['RDS_USERNAME'] %>
  password: <%= ENV['RDS_PASSWORD'] %>
  host: <%= ENV['RDS_HOSTNAME'] %>
  port: <%= ENV['RDS_PORT'] %>
.ebextensions

追加の設定を行う。

1. Rails Deploy 時、 rails db:seed が実行されないため、これを実装する。

container_commands:
  seeddb:
    command: 'export HOME=/root; rails db:seed --trace'
    leader_only: true

2. git が install されず、 bundle install に失敗するため、yum install git を追加する。

packages:
  yum:
    git: []

3. Healthcheck の URL を指定する

option_settings:
  - namespace:  aws:elasticbeanstalk:application
    option_name:  Application Healthcheck URL
    value:  /health_check.txt

4. Nginx の pubilc フォルダ設定が誤っているため、修正する

files:
  "/etc/nginx/conf.d/webapp_healthd.conf":
    mode: "000644"
    owner: root
    group: root
    content: |
      upstream my_app {
        server unix:///var/run/puma/my_app.sock;
      }

      log_format healthd '$msec"$uri"'
                      '$status"$request_time"$upstream_response_time"'
                      '$http_x_forwarded_for';

      server {
        listen 80;
        server_name _ localhost; # need to listen to localhost for worker tier

        if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
          set $year $1;
          set $month $2;
          set $day $3;
          set $hour $4;
        }

        access_log  /var/log/nginx/access.log  main;
        access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;

        root /var/app/current/public;

        location / {
          try_files  $uri @app;

          gzip_static on;
          gzip on;
          expires 60s;
          add_header Cache-Control public;
        }

        location @app {
          proxy_pass http://my_app; # match the name of upstream directive which is defined above
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }

      }

container_commands:
  01_reload_nginx:
    command: "service nginx reload"


5. RDSに繋ぐためのセキュリティーグループを追加する

option_settings:
  - namespace:  aws:autoscaling:launchconfiguration
    option_name:  SecurityGroups
    value:
      - rds-launch-wizard

6. ELB のポートを変更する

デフォルトのままだと、攻撃されやすいため、ポートを変更します。
ポートの追加を行うと、セキュリティーグループも自動で書き換えてくれます。
ここの設定も、追加の設定となるので、デフォルトの80ポートは、無効にします。

option_settings:
  aws:elb:listener:8080:
    ListenerProtocol: HTTP
    InstanceProtocol: HTTP
    InstancePort: 80

  aws:elb:listener:80:
    ListenerEnabled: false


7. コミットする

コミットしなければ、deploy に反映されない。

$ git commit -m 'hoge'
Elastic Beanstalk を作成する。
$ eb create {app name} \
-i t2.medium \
-r ap-northeast-1 \
--vpc.elbpublic \
--scale 2 \
--envvars RACK_ENV=production,SECRET_KEY_BASE=dafb6ff6cb0952c8842fd8c9419d3333ec5054ce7a9edbf8bc0c2abd012fc26ed94d0,S3_ACCESS_KEY_ID=AWDWDWDWDWDWW2A,S3_SECRET_ACCESS_KEY=UW/mKLUWm/fr4fFggs+5r39l5,S3_BUCKET=hoge-data,S3_ASSET_HOST=https://hoge.com/,RDS_DB_NAME=dbname,RDS_HOSTNAME=db.hoge.ap-northeast-1.rds.amazonaws.com,RDS_PORT=3306,RDS_USERNAME=username,RDS_PASSWORD=password
Cloud Front を使用する

beanstalk の ホスト名を Origin に指定するだけで良い。
キャッシュの時間設定は、Rails 側で指定する。

トラブルシューティング

起動に失敗する場合

ログを確認する

$ eb logs {app name}