LoginSignup
12
3

More than 5 years have passed since last update.

プルリクごとにレビュー用のサーバーレスアプリをデプロイする

Last updated at Posted at 2018-12-06

この記事はServerless Advent Calendar 2018の6日目です。

少し前までサーバーレスアプリを開発していましたが、最近転職したことで Ruby on Rails + heroku でのアプリ開発をしています。
なのでサーバーレスのネタは溜まっていませんが、その heroku に便利な機能があることを知り、サーバーレスでも使えそうだと思ったのでやってみます。
便利な機能というのが Review Apps というものです。

Review Apps とは

Heroku の Review Apps がどういうものか簡単に説明すると、
Review Apps の設定をした Git リポジトリで GitHub にプルリクが作られると、そのプルリクのソースコードを使って プルリクごとの環境を Heroku に構築 してくれる
というものです。

何が嬉しいか

デプロイされると URL エンドポイントもプルリクごとに作成されるので、動作確認したい場合はそのエンドポイントにアクセスすればよく、プルリクのブランチをローカルにプルしてきて起動して動作確認、みたいな手間が省けます。

サーバーレスアプリ開発でも使えそう!

これがめっちゃ便利だと思ったのでサーバーレスでもやってみます。
サーバーレスってどうしてもデプロイして動作を確認したくなるときがあるのですが、ステージごとに環境を作ると、「これから dev 環境にデプロイします」みたいな不毛なやり取りが発生するし、開発者ごとに環境を作ると、じゃあレビューしてもらう間の開発はどうするのよとなってしまうし、どうしたらいいのかという悩みはありました。
プルリクごとだといい感じじゃないですか?
(実際の開発でこの方法をやっていないのでどうなるかわからないですが。)

実行時だけ課金されるサーバーレスなのでレビュー用環境ぽこぽこ立てるのよさそうじゃないですか。

そして肝は デプロイごとに完全に分離された環境 ということです。アプリも DB も CFn スタックもです。

実装方法

実装方法は大体想像つきますよねー。GitHub のプルリクをフックできるCIサービスを使えばできそう。
今回は CodeBuild を使います。そのビルドの中でプルリクごとのソースをビルドしてデプロイできればよさそう。
デプロイには awslabs/aws-sam-cli を使います。

対象とするリポジトリは GitHub 上に存在する前提でいきます。
私は sam init --runtime python3.6 をしただけのリポジトリを作ってプッシュしておきました。

今回作ったリポジトリ ykarakita/serverless_review_apps

CodeBuild の設定

CodeBuild でプロジェクトを作成します。ソースプロバイダを GitHub に指定して、対象のリポジトリを選択します。このとき GitHub 連携が必要になります。
リポジトリを選択すると Webhook というチェックボックスが出てくるのでそれにチェックします。さっきやってみたところ、Codebuild のコンソールが新しいものになっていて、そこからだとチェックボックスが出てこなかったので、私はそっと古い画面に戻す設定をしました。

GitHub の設定

CodeBuild プロジェクトが作成できたら、 GitHub リポジトリの Settings ページに行きます。 Webhooks に Codebuild の webhook が追加されているはずです。

image.png

Edit から、Webhook を送信するアクションを指定できます。デフォルトで Pushes と Pull requests が有効になっています。今回はプッシュしたときにビルドが走らなくていいので Pushes のチェックをはずします。

とりあえず動かしてみる!

これで連携はできるようになったはずなのでプルリク出してみます。
requirements.txt の中身を消すプルリクでも出してみましょうか。

1206-1.png

おっ、動いてるっぽい
CodeBuild の方はどうだろう

1206-2.png

おっ動いてる。

連携の動作確認できました。 🍺
ただ、これだとビルド設定ファイルがリポジトリ内に存在しないのでビルドに失敗します。

CodeBuild はデフォルトで、ディレクトリ直下の buildspec.yml を見に行くので作成します。
とりあえずなんの意味もないやつを置きました。

buildspec.yml
version: 0.2

phases:
  install:
    commands:
      - ls
  build:
    commands:

これを追加したプルリクを出してみます。

1206-3.png

おっ通りました。
もちろんプルリクを出しているブランチにプッシュするたびにビルドが走ります。

プルリクごとにサーバーレス環境がデプロイされるようにする

サーバーレス環境がデプロイされるように buildspec.yml にコマンドを書いていきましょう。

プルリクごとの環境を作るので作成されるリソース名などはすべてプルリクのIDをつけていけばよさそう。
プルリクのIDは CodeBuild 実行環境の環境変数 CODEBUILD_WEBHOOK_TRIGGER で取得できます。
出力してみると pr/3 みたいな形で入ってました。
それをもとにリソースにつける名前の定義をします。

最終的にはこんな感じの buildspec ができあがりました。

codebuild.yml
version: 0.2

phases:
  install:
    commands:
      - pip install aws-sam-cli==0.6.1

  pre_build:
    commands: 
      - PR=`echo $CODEBUILD_WEBHOOK_TRIGGER | sed -e 's/\///'`
      - APP_NAME=my-review-apps-$PR
      - aws s3 ls s3://$APP_NAME 2> /dev/null || aws s3 mb s3://$APP_NAME

  build:
    commands:
      - pip install -r requirements.txt -t hello_world/build
      - cp hello_world/*.py hello_world/build/

      - sam package --template-file template.yaml --output-template-file serverless-output.yaml --s3-bucket $APP_NAME
      - sam deploy --template-file ./serverless-output.yaml --stack-name $APP_NAME --capabilities CAPABILITY_IAM

やっていることは、

  • ビルドしたソースを置くためのS3バケット作成(作成済みであればスキップ)
  • ライブラリのインストール
  • sam package
    • 作成したS3バケットを指定
  • sam deploy
    • 作成したS3バケットを指定
    • スタックネームを指定

これで再度プルリクを作成すると・・・

CloudFormation のコンソール画面
スクリーンショット 2018-12-06 22.56.15.png

プルリク単位のデプロイができた!
それぞれのリソースも見てみます。

API Gateway のコンソール画面
スクリーンショット 2018-12-06 23.12.52.png
Lambda のコンソール画面
スクリーンショット 2018-12-06 23.13.41.png
ちゃんとプルリク単位になってますねえ。

新しいプルリクが作成されたら新しいスタックが作成されます。
スクリーンショット 2018-12-07 0.03.29.png
うおおおお、これは便利なのでは。

TODO

これはジャストアイデアなのでもっといい方法があるかもしれないし、本当にこれで開発をするならもっと考慮しなくてはいけないことがあるかもしれない。
Heroku Review Apps は PR がマージなどでクローズされると環境も削除されます。今回やったやつは、自動で削除されないため別途、クローズされたら環境消すよ君を作る必要がある。

まとめ

CodeBuild 思ったより便利。 GitHub webhook とか環境変数とか、必要なものは揃っていた。

12
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
3