OpsWorks で 15分。光速 Rails アプリケーション デプロイメント。

# はじめに
この記事は、JAWS-UG KOBE の勉強会 [秋のデプロイ祭り](https://jaws-ug-kobe.doorkeeper.jp/events/52887) の発表資料です。

AWS のデプロイメントサービスである [OpsWorks](https://aws.amazon.com/jp/opsworks/) を使って、Rails アプリを短時間でデプロイしてみたいと思います。

それでは、早速いってみましょう！


# プロジェクトを作成してGitHubにアップ！

## プロジェクトの作成
Rails プロジェクトを作成します。

> rails new __sample_app__ -d mysql (-T)

* -Tはお好みで。
* sample_app は自分のプロジェクト名を。
* dbは RDSに接続することも考えて、mysql のほうが無難。(今回はEC2上のMySQLです）

## GemFile
今回の構成用に GemFileを修正します。

### コメントアウト
gem 'unicorn'
gem 'therubyracer', platforms: :ruby

### 追加
gem 'execjs'


## 適当にデータを入れてローカルで確認。
今回は、お友達リストを作りました。

> rails g scaffold friend name:string age:integer address:string mail:string
> rake db:create
> rake db:migrate
> rails s

![スクリーンショット 2016-10-19 14.14.17.png](https://qiita-image-store.s3.amazonaws.com/0/49986/12b37295-0c90-dbe6-df73-f4fe4dfd2c17.png)

ふむ。

## asset precompile 設定
Railsをデプロイするには、asset precompileして、jsやCSSなどを固めておく必要があります。
Railsのデプロイフックという機能を利用して、デプロイ時にassetをビルドします。

* deploy/before_migrate.rb というファイルを作成し、以下のコードを記述。
* 
```ruby:app/deploy/before_migrate.rb

        Chef::Log.info("Running deploy/before_migrate.rb")

        env = node[:deploy][:sample_app][:rails_env]
        current_release = release_path

        execute "rake assets:precompile" do
        cwd current_release
        command "bundle exec rake assets:precompile"
        environment "RAILS_ENV" => env
        end
```

このエントリが参考になります。
http://interu.hatenablog.com/entry/2013/08/01/214258

## GitHubにPUSH
この構成でGitHubにPUSHします。以下のリポジトリの構成を目指します。
https://github.com/jaws-ug-kobe/2016-10-19-deploy-fes

![スクリーンショット 2016-10-19 15.18.09.png](https://qiita-image-store.s3.amazonaws.com/0/49986/55231404-d8e1-dd46-82c4-9975caa592ea.png)

# OpsWorksの設定

## スタック

* ビルトインレシピが利用できるChef 11.10 のスタックタイプを利用
* デプロイ失敗したときに、失敗したマシンにログインしたいときがあるので、Default SSH key は設定しておくほうが何かと便利
* Custom JSON にデータベースの接続設定を書いておく。(Railsのdatabase.ymlがこの情報で上書きされます）

![スクリーンショット 2016-10-19 14.24.54.png](https://qiita-image-store.s3.amazonaws.com/0/49986/d0362be7-99c4-5822-840d-4ab656a97cdf.png)

![スクリーンショット 2016-10-19 14.22.54.png](https://qiita-image-store.s3.amazonaws.com/0/49986/1f2077e2-1de0-35e2-4182-fb4251a5e1ad.png)

```java:custom_json
{
    "deploy": {
        "sample_app": {
            "database": {
                "adapter": "mysql2",
                "username": "root",
                "password": "XXXXXX",
                "database": "XXXXXXXXX"
            }
        }
    }
}
```

Custom JSONに関してはこちらが参考になります。
https://docs.aws.amazon.com/ja_jp/opsworks/latest/userguide/customizing-rds-connect-customize.html


## レイヤー
先ほど作ったスタックにDBのレイヤーとApplicationレイヤーを追加します。

### Rails App Server レイヤー
webサーバーにはnginx、rackサーバーには Unicorn を利用します。
 
* Rails stack は、 nginx and Unicorn を選択

![スクリーンショット 2016-10-19 14.34.33.png](https://qiita-image-store.s3.amazonaws.com/0/49986/e7780e3f-5097-2683-e7ff-dfb0e1d85c3b.png)

### MySQL レイヤー

![スクリーンショット 2016-10-19 14.37.41.png](https://qiita-image-store.s3.amazonaws.com/0/49986/dc52c57a-8f4e-c2ab-31ed-bdb9e582c39b.png)

* ルートパスワードは適宜かえてください。

### インスタンスを追加
レイヤーを追加したら、それぞれのレイヤーでインスタンスをデプロイします。

![スクリーンショット 2016-10-19 14.41.25.png](https://qiita-image-store.s3.amazonaws.com/0/49986/820c3988-cef1-8da5-b4b4-fb7aa16fab26.png)

MySQLも同様に追加します。

## Appsの設定
デプロイするアプリケーションの設定をします。

* Name は Railsで作ったプロジェクト名と同じにする。(同じにしないとデプロイできません。)
* Data Sources は、__OpsWorks__ を選択。 RDSレイヤーのインスタンスを選択。データベースは、Custom JSONで指定したものを。
* Application Sourceは、GitHub のリポジトリを指定。
* Environment Variables に、 Railsが利用するSECRET_KEY_BASEを設定。(OpsWorksコンソール上で見えるのが嫌な人は、Protected Value にチェック）

> Application Source として、private リポジトリを設定する場合は、 Repository SSH Keyを設定します。
https://docs.aws.amazon.com/ja_jp/opsworks/latest/userguide/workingapps-deploykeys.html

 
![スクリーンショット 2016-10-19 14.46.49.png](https://qiita-image-store.s3.amazonaws.com/0/49986/8184df1c-390c-8e29-56c0-111117a54130.png)

![スクリーンショット 2016-10-19 14.47.02.png](https://qiita-image-store.s3.amazonaws.com/0/49986/d4725b63-fc77-4bdc-eb8c-2f5d1edb27d3.png)

SECRET_KEY_BASE は rake コマンドで生成します。

> rake secret

# デプロイメント

* Migrate database を YES にしてデプロイ
![スクリーンショット 2016-10-19 14.54.39.png](https://qiita-image-store.s3.amazonaws.com/0/49986/2b70dd3d-139a-ef73-3bee-d7f3508ee284.png)

![スクリーンショット 2016-10-19 14.56.55.png](https://qiita-image-store.s3.amazonaws.com/0/49986/4088978e-b075-0b09-6b9a-c65023f6babc.png)

ふむ。

#ロードバランサー
複数のインスタンスと高負荷のときにだけ起動するインスタンスを作り、フロントにロードバランサーを配置して、信頼性を高めます。

* ロードバランサーはEC2のダッシュボードから作成
* 現状OpsWorksで対応しているのは標準ロードバランサーのみ
* セキュリティグループはAWS-OpsWorks-LB-Serverを選択(ポート80,22,443のインバウンドを許可します）
* ヘルスチェックの対象ページは、/friendsを指定。（friendsモデルを作ったので）
* OpsWorksで作成したRails App Serverレイヤーのインスタンスを選択

## EC２ダッシュボードでの操作
![スクリーンショット 2016-10-20 4.52.39.png](https://qiita-image-store.s3.amazonaws.com/0/49986/720e3fe5-b1aa-c600-43ee-c5ac53b5fd73.png)

![スクリーンショット 2016-10-20 4.52.09.png](https://qiita-image-store.s3.amazonaws.com/0/49986/c4bc7b6b-7aef-a48e-4001-9bd3724e3d65.png)

![スクリーンショット 2016-10-20 4.53.50.png](https://qiita-image-store.s3.amazonaws.com/0/49986/eea6e7f5-b43d-611d-f79b-1807606a7597.png)

![スクリーンショット 2016-10-20 4.54.04.png](https://qiita-image-store.s3.amazonaws.com/0/49986/25529e67-7ac1-9189-2369-f281a569fd14.png)

![スクリーンショット 2016-10-20 4.54.28.png](https://qiita-image-store.s3.amazonaws.com/0/49986/7ea28f35-b06b-37ac-8a7e-c48b112cccfe.png)

![スクリーンショット 2016-10-20 4.55.10.png](https://qiita-image-store.s3.amazonaws.com/0/49986/2e313858-4ae6-4933-b979-12c9c8ee904e.png)

## OpsWorksダッシュボードでの操作

* Layers の Rails App Server の　Setting->Network の順に進み、ロードバランサーを選択
* ELBがデプロイされ、ヘルスチェックが疎通すれば、Health の欄が緑色になる。（デプロイされるまでは赤色）

![スクリーンショット 2016-10-20 5.04.30.png](https://qiita-image-store.s3.amazonaws.com/0/49986/bd33adfa-dc69-34d8-c701-9cdf50e9922a.png)

![スクリーンショット 2016-10-20 5.04.49.png](https://qiita-image-store.s3.amazonaws.com/0/49986/dd7bc148-3691-f4f0-5ac5-2d65fbb34fb9.png)

![スクリーンショット 2016-10-20 5.07.47.png](https://qiita-image-store.s3.amazonaws.com/0/49986/8bc9ef6f-64c4-a445-189a-406c6bf195c8.png)

![スクリーンショット 2016-10-20 5.06.08.png](https://qiita-image-store.s3.amazonaws.com/0/49986/8712d6bb-bf23-5443-e46f-f786ea7ecd93.png)

ふむ。

## 常時起動インスタンスと高負荷時のみ起動するインスタンスを追加
* 常時起動インスタンスは、最初にインスタンスを追加した要領でOK
* 高負荷時起動インスタンスは、Load-Based インスタンスを選択
* Load-Based　Configuration を有効にすること。(デフォルトはOFF)

![スクリーンショット 2016-10-20 7.33.45.png](https://qiita-image-store.s3.amazonaws.com/0/49986/59e2f02d-4387-32c9-c075-0eec67be95e7.png)

Load Based インスタンス
![スクリーンショット 2016-10-20 7.34.07.png](https://qiita-image-store.s3.amazonaws.com/0/49986/8fcdbf2f-5cc3-db2c-2a60-2a1300de1cbd.png)

#まとめ
* Custom JSONとデプロイフックだけきちんとする。