Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

自己紹介 樹下 稔 (KINOSHITA Minoru) ● KLab株式会社 ○ 技術統括部 バックエンドアーキテクチャグループ + 案件の仕事 ■ Jenkinsの話 ■ Unityのアセットバンドルビルドの話 ■ CIの話 ■ ... ○ 横断的に情報共有しつつ実案件での仕事ができるポジション

Slide 3

Slide 3 text

話す内容 ● AWS CodeBuildを使った並列CI環境構築 ● 目新しいことはあまりなく、事例の一つとして聞いてください

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

CI構成 ● 要件と方針 ● 全体構成 ● テストの実行 ● ログ

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

CI構成

Slide 9

Slide 9 text

CI構成 .buildspec/test1.yml .buildspec/test2.yml .buildspec/test3.yml 特定のディレクトリに buildspecファイルを複 数入れておく test1.yml test2.yml test3.yml Lambdaがbuildspecファ イル毎にCodeBuildを起 動する 全部終了したらGitHub Checksに結果を書き込む &Slackに通知

Slide 10

Slide 10 text

GitHub Checks

Slide 11

Slide 11 text

GitHub Checks

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

DBなどのサービス起動 ● docker in dockerができるイメージでdocker-composeを実行する ○ Pros ■ 開発用のdocker-composeをそのまま流用できる ■ ローカルでのCodeBuildのテストも可能になる ○ Cons ■ docker-composeのインストールやdockerdの起動など一手間必要 https://github.com/aws/aws-codebuild-docker-images ※CodeBuildのdockerイメージもある

Slide 16

Slide 16 text

ログ ● LambdaでCodeBuildの出力をGitHub Checksに書き込む ○ 権限の問題 ■ AWSのアカウントを持っていないメンバーもいる ■ GitHubなら全員アクセス可能 ○ 使いやすさの問題 ■ AWSに慣れていないメンバーが多い ■ CloudWatch Logsは使いにくい ■ GitHubから直接結果が見れると便利

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

テストの前準備に時間がかかる ● 前準備が(頑張って短縮して)3分程度 ○ リポジトリのセットアップ ○ docker imageのpull ○ テーブル作成、テストデータのinsert ● 前準備のオーバヘッドが大きいと並列数をあげても台数効果が出ない

Slide 20

Slide 20 text

リポジトリのセットアップについて ● たくさんのリポジトリをclone ○ メインのリポジトリとそのsubmodule ○ なぜか依存しているリポジトリとそのsubmodule ● リポジトリのcloneの仕方を工夫すると時間が削減できる ○ 不要なリポジトリがあるのではないかという話もありつつ…

Slide 21

Slide 21 text

リポジトリのセットアップについて ● 特定のブランチの最新コミットだけcloneする git clone --depth=1 --branch= ● DL量は減る

Slide 22

Slide 22 text

リポジトリのセットアップについて ● submoduleはブランチ名不明でハッシュしか分からないので git init git remote add origin git fetch origin --depth=1 git reset --hard FETCH_HEAD ● これが成功するのはが特定のrefに紐付いている場合のみ ○ そうでないときは失敗するので諦めて普通にcloneする

Slide 23

Slide 23 text

リポジトリのセットアップについて ● AWS CodeBuildにはローカルキャッシュの機能がある ○ ホスト上にdockerイメージやソースリポジトリを保存して使い回す機能 ○ 今回の場合ストレートには使えない ■ dindだったり独自にgit cloneしているため https://aws.amazon.com/jp/about-aws/whats-new/2019/02/aws-codebuild-now-supports-local-caching/ 任意のディレクトリをキャッシュできるのでやればできると思うが、キャッシュの生存期間は有限らしいので努力 に見合う効果があるのか?と思って試していない・・・

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

意外とコードを書いてしまった ● ありものを使うので自前の処理はそこまで多くない想定だった ● 実際にはLambda(js)を500行程度書いた ○ buildspecファイルを探して指定 ○ ビルド時間に制限 ○ 通知先チャンネルの指定 ○ テストが全部終了したことを確認して通知 ● 保守コストをほぼなくせるのではないかという目論見は外れた

Slide 26

Slide 26 text

意外とコードを書いてしまった ● 汎用性(別リポジトリでの利用)のため独自CI機能を実装した ○ .buildspec/meta.yml ■ 複数ビルドがすべて終了したときにどのチャンネルに通知するか ■ pushイベントに対して自動的にビルドを実行するブランチの指定 ● releaseブランチなど ○ 既存CIサービスと比較すると当然見劣りする ■ 頑張って作る必要があるかどうか微妙

Slide 27

Slide 27 text

まとめ ● CodeBuildを使った並列ビルド環境を作った ○ Lambdaでリポジトリの設定を読み込みCodeBuildを複数起動する ○ GitHubからログが見れて便利 ● 思ったよりコードを書いてしまった問題 ○ 保守コストに難 ● リポジトリのセットアップに時間がかかる問題 ○ cloneの仕方を工夫してある程度解決