Beeeat’s log

Beeeat’s log

プログラミングで出くわした知識やツール、日常生活、働き方その他色々なことをメモしていくブログ

シス担ミートアップ#3 で AWS CodeBuild を CI 環境として使ってみた話をしました

9月頃になりますが「シス担ミートアップ」という社内イベントに登壇しました.イベント自体は3回目で,グループイン企業や投資先企業のエンジニアも参加し,様々な知見の共有や交流し,充実したイベントとなりました.

このイベントで私は, AWS CodeBuild(以下,CodeBuild) を CI として使ってみた話をしました.今回は登壇した資料についての補足や発表時にあまり話せていなかった内容を書いていこうと思います.

登壇資料

CircleCI のテスト実行待ち問題

f:id:bake0937:20191215170316p:plain

当時のマイナビニュースでは CircleCI の「コンテナ課金プラン」を利用していました.CircleCI は GitHub.com の Organization 単位で利用することができます.Organization には他チームのリポジトリもあるため,CircleCI のコンテナを他チームと共同で利用することになります.

これにより,マイナビニュースで CircleCI を利用している時に他チームのテストの実行待ちが頻繁に発生し,開発の進捗が遅れるという問題が発生しました.

マイナビニュースが他の CI サービスに移行

f:id:bake0937:20191215171914p:plain CircleCI の契約コンテナ数を増やす案や DroneCI などの CI 環境を構築する案など,調査・検討をしましたが,その中で CodeBuild を CI として利用する事例があることを知りました.

他の企業での事例は少なかったですが,従量課金制で並列実行できる点やマイナビニュースでは既に AWS をインフラとして利用していたため導入が早いと判断し,CodeBuild を CI として利用することにしました.

CodeBuild では CircleCI のような複数のコンテナ指定ができない...

f:id:bake0937:20191215173050p:plain 設定用の yml ファイル(buildspec.yml)の書き方が少し異なることや CI のログは CloudWatch Logs が必要になるなどの変更点はありましたが,ここまでで CircleCI との大きな違いはありませんでした,

しかし.一番の大きな違いは CodeBuild で設定する yml ファイルや CodeBuild のコンソール画面で複数のコンテナを指定することができないという点でした.CircleCI を利用していた時は Web や DB など複数のコンテナがある構成であったため,CodeBuild ではどのように表現すれば良いのか?というところでとても悩みました.

Docker in Docker で 複数のコンテナを利用することを表現する

f:id:bake0937:20191215173857p:plain 複数コンテナを指定する方法についてさらに調べたところ,コンテナの中にさらに複数のコンテナを指定する Docker in Docker (以下,dind) を使った方法を知りました.

Docker 社が Docker Hub で配布している dind 用のコンテナイメージ CodeBuild のコンソールで指定し, 設定用の yml ファイルにdocker pullコマンド記載し,テストの実行に必要なコンテナイメージを pull する方法です.

hub.docker.com

他の企業での事例が少ないこともあり,挑戦するのがとても不安でしたが,何とか上記の構成で CI 環境を構築することができました.CodeBuild のコンソールでのコンテナの指定方法や設定用の yml ファイルの書き方については,スライドを見てみてください.

こうして現在では,CI 環境としてマイナビニュースは CodeBuild,他チームは CircleCI を利用しています.

CI の速度改善を試みる

f:id:bake0937:20191215175658p:plain 「CodeBuild で CI 環境を構築できた!!めでたしめでたし...」という訳にもいかず,今度は CI の実行時間が遅いという課題が発生しました.

速度改善には色々な方法があるのですが,一番効果が高かったのは,CodeBuild のローカルキャッシュ機能の一つである「DockerLayerCacheをオン」する方法でした.この機能をオンにすることで,ビルドで利用した Dockerfile レイヤーを再利用することでき,結果として約9分短縮されました.

他のローカルキャッシュ機能やコンピューティングタイプを上げ,最終的には約25分→約13分代まで CI の実行時間を短縮することに成功しました.

この速度改善から数ヶ月後にソリューションアーキテクトの方とお話をする機会がありました.その時に今回やったことについて話した所,ローカルキャッシュ機能はあくまでベストエフォートな機能で,ビルドの間隔が空いた場合やビルドの並列度が高い(同じ時間に複数のビルドが実行される)場合はキャッシュが効かない時があるという話を聞きました.

これは実際に利用している私自身も「あれ?今回のビルドはキャッシュが効いてないな」と思う場面が何度かあり,納得しました.

その他運用していて遭遇したこと

他に遭遇したこととして,Codebuild 側で Linux コマンドなどのバージョンが上がった時に設定用の yml ファイルにあるコマンドのオプションの指定方法が変わったことで,CI が落ちることが何度かありました.その一例として過去に記事を書いております.

bake0937.hatenablog.com

CodeBuild を利用するようになって,開発メンバーが約4人で月額の平均が約2000円とだいぶコストカットすることに成功しました.

しかし,上記のような管理コストも考えると,新たなプロダクトがリポジトリに追加され,そのプロダクトでも CI が必要になった時は,CircleCI や TravisCI などの CI サービスを利用することや DroneCI や Jenkins など違う種類の CI 環境の構築することなどを再検討してみても良いと考えました.

最近,CircleCI に 「Performanceプラン」という新しいプラン*1が登場したため気になっています.

まぁ CodeBuild の方が金銭コストが低く CI 環境を構築できることがわかってしまったので,開発効率を優先するのか,それとも金銭コストを優先するのかなどを開発チームや事業部全体で議論する必要があるかと思います.

circleci.com

まとめと所感

シス担ミートアップ#3 に登壇しました.当時の私の AWS の利用経験は Amazon S3 を少し使ったことあるくらい(前職では OpenStack によるプライベートクラウドをメインで利用していました)で,「そもそも AWS について色々調べないと!」みたいな状態でした.そのため,今回経験したことを通して AWS についてもよく知ることができたため,とても良い経験になりました.

また, CI 環境...というより,技術選定はパフォーマンスや開発効率を優先するだけではなく,選定したサービスやツールの金銭コストや運用コストについても考慮する必要があることを思い知らされました.

その点では技術選定の経験もできたため,これからも「発生している問題や課題に対して,解決をする方法」についての考え方やセンスを磨いていこうと思います.

*1:当時(CodeBuild への移行作業をしている時)は「Performanceプラン」が出るらしいというのを噂で聞いた状態でした.