LCL Engineers' Blog

バス比較なび・格安移動・バスとりっぷを運営する LCLの開発者ブログ

1環境あたり月約2.7USDで、ECS Fargateを使ってブランチ毎にQA環境を自動生成した話

こんにちは。id:kasei_san です

バス比較なびのバスツアー検索サービスにて、ブランチ毎にECS FargateでQA環境を自動生成する仕組みを格安で作成したので、ドヤりたくなり記事を書きました!

課題

バス比較なびのバスツアー検索サービス(以降「バスツアー」)では、動作確認環境が stage 環境しかありませんでした。 そのため、以下のような事象が発生し、デリバリー速度が低下するという課題がありました。

  • stageでの動作確認がボトルネックになり、、他の修正をstageに上げたり、リリースすることができない
  • 大きい修正もすべて完了してからstageにあげていたので、手戻りが発生することがあった

解決方法

解決のためにチームで話し合い、ブランチ毎に環境があれば、待ちも発生せず、作りかけの時点で確認してもらうこともできる。となりました。

どういうものを作ったか

このようなものを作成しました。

f:id:kasei_san:20200314164143p:plain
QA環境自動生成構成図

処理の概要

  • AWS Codebuild が git push で発火。docker image ビルド後、QA環境生成の API Gateway を実行
  • Amazon API Gateway が QA環境を生成する AWS Lambda を実行
  • AWS Lambda により作成された、QA環境の service を Amazon ECS が実行

処理の詳細

  1. ユーザがブランチを切って、git push する
  2. Codebuild が PUSH イベントを受信。master ブランチ以外の場合、buildspecを起動
  3. buildspec は、以下の処理を行う
    • docker image のビルド
    • docker image に、${ブランチ名}_${commit hash} という tag をつける
    • docker image を ECR に push
    • QA環境を生成するAPIを叩く
  4. API Gateway が QA環境を生成する lambda を実行
  5. lambda は、以下の処理を行う
    • ロググループを CloudWatch Logs に生成
    • task definition を ECS に設定
    • ターゲットグループを作成
    • service を設定し、task definitionとターゲットグループを紐付ける
    • QA専用の Application Load Balancer に listenerルールを追加。ロードバランサとターゲットグループを紐付ける
    • route53 で、QA環境用のドメインとロードバランサを紐付ける resource record set を設定
  6. 生成されたドメインをslackに通知

f:id:kasei_san:20200314170053p:plain

補足

  • 上記はAPIのQA環境生成の通知です。front用にも同様の環境を作成しています
  • Application Load Balancer はQA環境全体で1つです。これは、リージョンあたりのロードバランサーの上限が50個のためです
  • また、これと別に、GitHub Actionにより、branchがcloseされた時に、上記の環境を削除する lambda も作成しました

その他のポイント

また、QA環境のECSでは、Fargate Spotを使用しています。

Fargate Spot は、不意に中断することがある代わりに、通常と比べて70%OFFで Fargate が利用できるサービスです。

aws.amazon.com

Fargate Spot と 営業時間外に task を停止することにより、QA環境をかなりの低コストで運用できるようになりました!

Fargate代金だけならば、具体的には、1日14H、週5日稼働で、1環境あたり 約 2.65USD/月となりました! 安い!!

コスト内訳

  • CPU: 0.01553717USD/CPU単位 x 0.25cpu単位 x 14H x 5日 x 4週間 x 2(APIとfront) ≒ 2.17USD/月
  • memory: 0.00169938USD/GB単位 x 0.5GB単位 x 14H x 5日 x 4週間 x 2(APIとfront) ≒ 0.48USD/月

得られた知見

QA環境を作成して得られた知見は以下のようなものでした。

  • AWS Codebuildは、発火条件をブランチ名でフィルタリングできる
    • 当初、AWS CodePipeline でやろうと思ったのですが、AWS CodePipeline は発火条件をブランチ名でフィルタリングできないのですね...
  • Fargate Spot 安い!

反省点

また、作った後に「こうすればよかった」という以下のような反省点がありました。

QA環境生成をAPIにする必要はなかった

API Gatewayを使用せず、直接 lambda を叩いたほうがシンプルでした...。

  • API Gatewayは、後からAPIを変更せずにバックエンドを変えられることにメリットがあるが、今回はその必要は無いため

AWS Codebuild ではなく、GitHub Actions を使ったほうが良かった

AWS Codebuildは、ブランチの削除をcatchすることができません。そのため、QA環境削除は GitHub Actions で作ることになってしまいました。 結果として、QA環境の生成と削除で、実行環境が分かれてしまいました...。

結果論ではありますが、QA環境の生成も最初から GitHub Actions で作った方が良かったのかなぁ...と思っています。

  • ビルド時にVPCを経由する必要もありませんでしたし...

まとめ

多少の反省点はありましたが、素早く自動的にQA環境が生成されるようになり、開発やメンバーの動作確認もスムーズになったと思われます

また、やっぱり環境が自動的にできる仕組みを作るのって楽しいですね!!

JOIN US!!

LCLではこのような自動化による開発の効率化に興味があるエンジニアを募集中です!

www.lclco.com