AWS CodeBuildにRailsのテストを実行してもらう

[株式会社LITALICO](http://litalico.co.jp/)でエンジニアをやっております@Takuan_Oishiiです。
この記事は『[LITALICO Advent Calendar 2016](http://qiita.com/advent-calendar/2016/litalico)』23日目の記事です.

23日目は[AWS re:Invent 2016](https://reinvent.awsevents.com)で発表されたAWS CodeBuildでRailsのテストを実行してもらう話をお届けします🎁
CIツールを検討しているRails開発者の方の参考になれば幸いです.

# <i class="fa fa-youtube-play"></i> はじめに
テスト, してますか? ~~セコム, してますか?~~
LITALICOではCircleCIを使ってRailsアプリに対してRSpecで記述したテストを実行しています.
GitHubにブランチをpushする, あるいはpull requestをマージすると自動でCircleCIが該当ブランチのテストを実行してくれるようにしています.

最近はコードレビューの負担減などを目的に, プルリクを小さく出すことを意識しています.
同じプルリクに含まれていなくても構わない変更を極力別のプルリクに分けることで, いつまでたってもレビューを通らずになかなかデプロイされないという事態に陥ってしまうブランチを減らすことに成功しました💪

しかし, テスト実行時間の増加や開発メンバーの増加によって, **CircleCIのテスト実行待ちの渋滞**が発生するようになってしまいました.
この問題は**CircleCIに札束を積んで同時に実行できるインスタンス数を増やす**, もしくは**そもそもテスト実行時間を短縮する**などの解決策があります.

先日開催されたAWS re:Invent 2016は, この問題に対してAWS CodeBuildという別の解決策を提示してくれました.

ということでこの記事では, お試しで(あくまでお試しで)CodeBuildにRailsアプリのテストをやってもらう手順紹介をします. 
お試しなのでRSpecではなくmini testを使いますが, 話としてはあまり変わらないはずだと思います.

# <i class="fa fa-question-circle-o"></i> CodeBuildとは
CodeBuildがどんなサービスなのかについてはAWSブログ([AWS CodeBuild ― フルマネージドのビルドサービス](https://aws.amazon.com/jp/blogs/news/aws-codebuild-fully-managed-build-service/))などで解説されているのでここで解説はしませんが, 今回抑えたいポイントとしてはCodeBuildは**従量課金制**であるということです.

同時実行数などに制限がなく, 1分実行する毎に何ドルという形で課金がされていきます.
この特徴があるため, **｢使わないときは一切課金されず, 使いたいときには無限にスケールしてくれてバカスカ使えるCIサービス｣**として, 他のCIサービスの代替となるのではないかと考えています.

※実際のところ, CircleCIに札束を積んだ場合とCodeBuildを利用した場合でどっちが安いのかの見積もりはしてません. 業務で使うとしたらノーストレスなCIの代償としてCodeBuildにさらなる札束を積むことになるのかもしれませんがよくわかりません.

# <i class="fa fa-code"></i> Railsアプリの準備
[Ruby on Rails チュートリアル](http://railstutorial.jp/chapters/toy_app?version=5.0#cha-a_toy_app)2章のtoy_appをgenerateするときに自動で生成されるテストをCodeBuildで実行してみることにします.

toy_appを用意したら, リポジトリのルートディレクトリに`buildspec.yml`というファイルを作成し, 中身を以下のようにしてcommitします.

```
version: 0.1

phases:
  install:
    commands:
      - echo install started on `date`
      - sudo apt-get update
      - sudo apt-get -y install nodejs
      - sudo apt-get -y install npm
      - sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10
      - gem install bundler
      - bundle install
  build:
    commands:
      - echo Build started on `date`
      - bundle exec rails test
  post_build:
    commands:
      - echo Build completed on `date`
```

あとはこのリポジトリをGitHubにpushすればリポジトリの準備は完了です.

今回使ったリポジトリのURLを示しますので参考程度にご覧ください.
https://github.com/takuan-oishii/toy_app

# <i class="fa fa-gears"></i> Build projectの準備
AWSマネジメントコンソールのサービス一覧からCodeBuildのマネジメント画面を開きましょう.

CodeBuildは記事執筆時点では東京リージョンでの利用は不可能です.
東京などの利用不可リージョンを選択していると｢バージニア, オレゴン, アイルランドのどれかのリージョンにしろ｣と言われるので従いましょう.
利用可能リージョンが選択されていれば, 空のBuild projects一覧が表示されるはずです.
｢Create project｣を押してprojectを作りましょう.

| 項目 | 値 |
|:-----------|:------------|
| Project name       |   なんでもOK|
| Source provider     |      GitHub |
| Repository     |        用意したリポジトリ名 |
| Image       |          aws/codebuild/ruby:2.3.1 |
|Current build specification|Using buildspec.yml in the source code root directory|
|Artifacts type|No artifacts|

といった感じで入力していき, プロジェクトを作成します.

作成が完了してBuild projectの一覧に今作成したプロジェクトが表示されていればOKです!

# <i class="fa fa-spinner fa-spin"></i> 実行してみよう!
Build projectの一覧からプロジェクトを選択し, ｢Start build｣をクリックします.
実行時の個別設定ができる画面が表示されますが, 全てデフォルトのままで｢Start build｣をクリックして構いません. クリックすればテストが実行されます!

数分待てばPhase detailsが｢Succeeded｣で埋まっていき, テストが完了します.
![スクリーンショット 2016-12-22 0.40.19.png](https://qiita-image-store.s3.amazonaws.com/0/48596/be4af205-1edf-0cbe-8e74-3e99c6d2f6e6.png)

Build logsの｢View entire log｣をクリックしてログも見てみましょう.
![スクリーンショット 2016-12-22 0.45.41.png](https://qiita-image-store.s3.amazonaws.com/0/48596/de8755a5-6035-d8ec-7481-13333fc611b7.png)

ターミナルで実行するのと違って少々読みづらいですが, mini testのログが出て12件のテストにパスしていることがわかりますね.

ためしにわざとテストがfailするようなcommitをGitHubにpushしてCodeBuildでテストが失敗する様子を見てみましょう.
![スクリーンショット 2016-12-22 0.53.50.png](https://qiita-image-store.s3.amazonaws.com/0/48596/ae71a6ea-c9be-6caa-cf98-2606a1740f6c.png)
先程と同じくやたら見づらいログですが, `users_controller.rb`の41行目のテストが失敗していることがわかります.

さっくりテスト実行できましたね!!!!

# <i class="fa fa-pencil"></i> おわりに
とてもさっくりとテストが実行できることがわかりました.

私のチームでは, pushにhookしてCIを実行する, CIの実行結果をslackに通知するなどの連携を行っていますが, このへんもさっくり設定できるならCodeBuildは結構使い勝手のいいサービスなんじゃないでしょうか.

今回のRailsアプリでは色々と面倒だったのでsqliteを使用していますが, これが例えばMySQLになったり, もっと色々な要求があったりしたとしても, 実行イメージとしてDockerのイメージを渡すようにすればなんでも対応できると思います.

CIもAWSで賄えるとなれば, また1つ管理が楽になる気がしますね!
LITALICOでももう少しCodeBuildの使い勝手を検証してみて, 良さそうなら業務に導入してみたいと(個人的に)思っています!!

さて明日の[LITALICO Advent Calendar 2016](http://qiita.com/advent-calendar/2016/litalico)は@pabroffさんの｢クリスマスだろうが休めないボッチ管理者向けの何か｣です. お楽しみに.