AWS CodeBuild をローカルでデバッグする CodeBuild Local 入門


簡単に

  1. https://github.com/aws/aws-codebuild-docker-images を clone
  2. aws-codebuild-docker-images/ubuntu/standard/2.0/Dockefile をビルド ( これがビルド用イメージになる )
    • マシンスペックにもよりますが、 Core i7 の Macbook で 20 分程度かかりました
  3. ヘルパースクリプト aws-codebuild-docker-images/local_builds/codebuild_build.sh を利用して CodeBuild Local 起動
Getting-started
$ git clone https://github.com/aws/aws-codebuild-docker-images.git
$ docker build -t aws/codebuild/standard:2.0 ./aws-codebuild-docker-images/ubuntu/standard/2.0/
$ ./aws-codebuild-docker-images/local_builds/codebuild_build.sh -i aws/codebuild/standard:2.0 -s /path/to/src -a ./artifacts

CodeBuild の buildspec.yml のデバッグがつらい!!

CodeBuild の buildspec.yml を書いているとき、こんなことありませんか?

  • buildspec.yml のちょっとした修正の動作確認をしたいけど、この修正でいいかわからない
  • 修正途中のコミットを push したくない、後でコミットログを整理したくない
  • 修正途中のソースでパイプラインが走りきって、ビルドされたコンテナイメージをリポジトリに push してしまうとまずい
  • CodeBuild の待ち時間が長い

それ、 CodeBuild Local なら解決できるかもしれません。

CodeBuild Local とは ?

aws/aws-codebuild-docker-images - GitHub

  • AWS が提供する CodeBuild のビルド用イメージの Docker ファイルと、それを動かすための Agent Docker イメージとヘルパースクリプト
  • ローカルで buildspec.yml を走らせてデバッグできる
  • 本物の CodeBuild 同様、複数ソースをインプットとしたり、アーティファクトの出力もできる

やってみよう !

CodeBuild Local を簡単に体験できる Makefile を書きました。
使い方がわかってきたら、実際にプロダクトに組み込んでみると良いと思います。

ikasam/codebuild-local-getting-started - GitHub

getting-startedの使い方
$ git clone https://github.com/ikasam/codebuild-local-getting-started.git
$ cd codebuild-local-getting-started
$ make

動作確認環境

  • Docker Desktop for Mac v2.1.0.1 (37199)
    • Engine: 19.03.1
  • GNU Make 3.81

ヘルパースクリプト codebuild_build.sh の使い方がわかれば CodeBuild Local が分かる!!

ヘルパースクリプトがやっていること

スクリプトに渡されたオプションから、実際に実行する docker コマンドを組み立てて実行します。最終的にどういうコマンドが実行されるかは、スクリプト実行時の最初に表示されます。

$ ./aws-codebuild-docker-images/local_builds/codebuild_build.sh \
-i aws/codebuild/standard:2.0 -e ./codebuild.local.env -s . -a ./artifacts
Build Command:

docker run -it -v /var/run/docker.sock:/var/run/docker.sock -e \
"IMAGE_NAME=aws/codebuild/standard:2.0" \
-e "ARTIFACTS=/Users/m_kanno/ikasama/codebuild-local-getting-started/artifacts" \
-e "SOURCE=/Users/m_kanno/ikasama/codebuild-local-getting-started/." \
-v "/Users/m_kanno/ikasama/codebuild-local-getting-started:/LocalBuild/envFile/" \
-e "ENV_VAR_FILE=codebuild.local.env" \
-e "INITIATOR=m_kanno" amazon/aws-codebuild-local:latest

※ 見やすさのために出力を改行しています

少しクセのあるオプションたち

ここの README にだいたいのことが書いてありますが、少しクセがあるので補足説明をしておきます。

オプション 意味 必須?
-i ビルド用イメージ
-a アーティファクト出力先
-l agent イメージを指定する
-c AWS CLI の設定
-p AWS CLI のプロファイル
-b buildspec.yml の指定
-e 環境変数
-m ソースディレクトリをホストから Volume Mount
-s ソースディレクトリの指定

-i ビルド用イメージ

  • カスタム用ビルドイメージはここで指定します

-c, -p AWS CLI の設定、プロファイル

  • ~/.aws/config, ~/.aws/credential をビルド用イメージ内にコピーします
  • 例えば、 AWS のリソースにアクセスする際に必要です
    • ECR からイメージを pull するとか
  • プロファイルを指定したい場合は -c に加えて -p your_profile も指定します

-e 環境変数

  • ファイルだけ渡せる
  • -e MYENV=hoge というような渡し方はできません
  • 一般的な env ファイルフォーマット
    • 細かい仕様は README に書いてあります
  • ローカルで走らせたくない処理があるときは、環境変数で制御すると良いです
    • CODEBUILD_CI は CodeBuild 上では true となるので、ローカルでは false を渡して if で分岐するとか
環境変数で制御する例
if $CODEBUILD_CI; then echo This line is executed only in the real CodeBuild environment; fi

-m ソースディレクトリをホストから Volume Mount

  • うまく使うとソース転送時間を短縮できます
  • マウント先にビルドの中間生成物を作ったあと削除しないと、ホスト上に中間生成物が残ります

-s ソースディレクトリの指定

  • 省略するとカレントディレクトリをソースとします
  • 複数ソースを指定する場合、 2 つ目以降は -s <sourceIdentifier>:<sourceLocation> の形式で指定します
  • buildspec.yml の中では、 $CODEBUILD_SRC_DIR_<sourceIdentifier> で参照できます 1

2 つの異なる Docker イメージ

ビルド用イメージ

ビルド環境となる Docker イメージです。
CodeBuild が標準で提供しているイメージを利用したり、プロジェクトによってはカスタムイメージを用意します。 getting-started では CodeBuild 標準の aws/codebuild/standard:2.0 を利用しています。
aws/codebuild/standard:2.0 は、CodeBuild のコンソールでは環境設定で設定します。

CodeBuild Local Agent (agent イメージ)

AWS CodeBuild Local Builds

CodeBuild をエミュレートする Docker イメージです。
こいつが buildspec.yml を解釈し、ビルド用イメージ上でのビルドを指示します。
Dockerfile などは公開されていおらず2、 Docker Hub からイメージを pull して利用します。

CodeBuild Local の制限事項

buildspec.yml 上での Docker の Volume mount がうまく動きません。
これは、以下の環境差異によるものです。

  • CodeBuild: OS 3上の Docker でビルド用イメージを動かす
  • CodeBuild Local: Docker コンテナ (agent) からホスト OS の Docker でビルド用イメージを動かす

Docker デーモンが動いている場所とマウントしようとする場所が違うので、 CodeBuild Local では Volume mount がうまく動きません。4

まとめ

  • CodeBuild Local で buildspec.yml を手軽に動作確認できます
  • CodeBuild Local を簡単に体験できる Makefile を作りました。ぜひ試してみてください!
  • ヘルパースクリプト codebuild_build.sh の使い方をマスターしよう!
  • 一部制限事項があるので、気をつけましょう

参考


  1. Primary Source は $CODEBUILD_SRC_DIR 

  2. CodeBuild のリファレンス実装だからかな? 

  3. たぶん EC2 

  4. 個人的には CI のパイプラインで Docker Volume Mount するのはあまり筋が良くないと思うので避けたほうがいいと思います