AWS CodeBuildを使ったCI環境の構築

AWS CodeBuildを使ったCI環境の構築

E4a2e149630d63b81292f6e4fddb7a3b?s=128

KINOSHITA Minoru

October 02, 2019
Tweet

Transcript

  1. AWS CodeBuildを使った CI環境の構築 2019/10/02 CI/CD Test Night #5

  2. 自己紹介 樹下 稔 (KINOSHITA Minoru) • KLab株式会社 ◦ 技術統括部 バックエンドアーキテクチャグループ

    + 案件の仕事 ▪ Jenkinsの話 ▪ Unityのアセットバンドルビルドの話 ▪ CIの話 ▪ ... ◦ 横断的に情報共有しつつ実案件での仕事ができるポジション
  3. 話す内容 • AWS CodeBuildを使った並列CI環境構築 • 目新しいことはあまりなく、事例の一つとして聞いてください

  4. 目次 • 背景 • CI構成 • 工夫した点、なんとかしたい所

  5. 背景 • 案件のメインのサーバリポジトリは自動テストが1時間以上かかる ◦ 以前はローカルマシンでやっていた(手動) • AWSが案件で既に利用中だったので、CodeBuildを使った構成を考えた ◦ CircleCIとかは導入してないので ◦

    やってみたいからやった、という気持ちも少なからず...
  6. CI構成 • 要件と方針 • 全体構成 • テストの実行 • ログ

  7. 要件と方針 • 並列でビルドできること • なるべく手間をかけないで保守できるようにする →LambdaでCodeBuildを複数起動しよう

  8. CI構成

  9. CI構成 .buildspec/test1.yml .buildspec/test2.yml .buildspec/test3.yml 特定のディレクトリに buildspecファイルを複 数入れておく test1.yml test2.yml test3.yml

    Lambdaがbuildspecファ イル毎にCodeBuildを起 動する 全部終了したらGitHub Checksに結果を書き込む &Slackに通知
  10. GitHub Checks

  11. GitHub Checks

  12. CI構成 CodeBuild(buildspec)で対応していないこと、工夫した点 1. 分割して並列実行 2. DBなどのサービス起動 3. ログ閲覧

  13. テストの分割&並列実行 • ベースとなるjsonnetファイルから複数のbuildspecファイルを生成する • buildspecファイルは全てリポジトリにコミット • Lambdaがそれぞれのbuildspecファイルに対してCodeBuildを起動 phases: build: ...

    phases: { build: { .... }}
  14. jsonnet test.jsonnet local Test(name) = { person: { name: name,

    welcome: "Hello " + name + "!" }, }; { "test-alice.yml": std.manifestYamlDoc(Test("Alice")), "test-bob.yml": std.manifestYamlDoc(Test("Bob")) } test-bob.yml "person": "name": "Bob" "welcome": "Hello Bob!" test-alice.yml "person": "name": "Alice" "welcome": "Hello Alice!" $ jsonnet -S -m . test.jsonnet
  15. DBなどのサービス起動 • docker in dockerができるイメージでdocker-composeを実行する ◦ Pros ▪ 開発用のdocker-composeをそのまま流用できる ▪

    ローカルでのCodeBuildのテストも可能になる ◦ Cons ▪ docker-composeのインストールやdockerdの起動など一手間必要 https://github.com/aws/aws-codebuild-docker-images ※CodeBuildのdockerイメージもある
  16. ログ • LambdaでCodeBuildの出力をGitHub Checksに書き込む ◦ 権限の問題 ▪ AWSのアカウントを持っていないメンバーもいる ▪ GitHubなら全員アクセス可能

    ◦ 使いやすさの問題 ▪ AWSに慣れていないメンバーが多い ▪ CloudWatch Logsは使いにくい ▪ GitHubから直接結果が見れると便利
  17. 工夫した点、なんとかしたい点 • 前準備に時間がかかる • 意外とコードを書いてしまった

  18. 工夫した点、なんとかしたい点 • 前準備に時間がかかる • 意外とコードを書いてしまった

  19. テストの前準備に時間がかかる • 前準備が(頑張って短縮して)3分程度 ◦ リポジトリのセットアップ ◦ docker imageのpull ◦ テーブル作成、テストデータのinsert

    • 前準備のオーバヘッドが大きいと並列数をあげても台数効果が出ない
  20. リポジトリのセットアップについて • たくさんのリポジトリをclone ◦ メインのリポジトリとそのsubmodule ◦ なぜか依存しているリポジトリとそのsubmodule • リポジトリのcloneの仕方を工夫すると時間が削減できる ◦

    不要なリポジトリがあるのではないかという話もありつつ…
  21. リポジトリのセットアップについて • 特定のブランチの最新コミットだけcloneする git clone --depth=1 --branch=<branch> <repository> • DL量は減る

  22. リポジトリのセットアップについて • submoduleはブランチ名不明でハッシュしか分からないので git init git remote add origin <repo>

    git fetch origin --depth=1 <hash> git reset --hard FETCH_HEAD • これが成功するのは<hash>が特定のrefに紐付いている場合のみ ◦ そうでないときは失敗するので諦めて普通にcloneする
  23. リポジトリのセットアップについて • AWS CodeBuildにはローカルキャッシュの機能がある ◦ ホスト上にdockerイメージやソースリポジトリを保存して使い回す機能 ◦ 今回の場合ストレートには使えない ▪ dindだったり独自にgit

    cloneしているため https://aws.amazon.com/jp/about-aws/whats-new/2019/02/aws-codebuild-now-supports-local-caching/ 任意のディレクトリをキャッシュできるのでやればできると思うが、キャッシュの生存期間は有限らしいので努力 に見合う効果があるのか?と思って試していない・・・
  24. 工夫した点、なんとかしたい点 • 前準備に時間がかかる • 意外とコードを書いてしまった

  25. 意外とコードを書いてしまった • ありものを使うので自前の処理はそこまで多くない想定だった • 実際にはLambda(js)を500行程度書いた ◦ buildspecファイルを探して指定 ◦ ビルド時間に制限 ◦

    通知先チャンネルの指定 ◦ テストが全部終了したことを確認して通知 • 保守コストをほぼなくせるのではないかという目論見は外れた
  26. 意外とコードを書いてしまった • 汎用性(別リポジトリでの利用)のため独自CI機能を実装した ◦ .buildspec/meta.yml ▪ 複数ビルドがすべて終了したときにどのチャンネルに通知するか ▪ pushイベントに対して自動的にビルドを実行するブランチの指定 •

    releaseブランチなど ◦ 既存CIサービスと比較すると当然見劣りする ▪ 頑張って作る必要があるかどうか微妙
  27. まとめ • CodeBuildを使った並列ビルド環境を作った ◦ Lambdaでリポジトリの設定を読み込みCodeBuildを複数起動する ◦ GitHubからログが見れて便利 • 思ったよりコードを書いてしまった問題 ◦

    保守コストに難 • リポジトリのセットアップに時間がかかる問題 ◦ cloneの仕方を工夫してある程度解決