CodeBuild をローカル環境で実行(テスト、デバッグ)できるようになりました
CodeBuild の処理をローカルで動作確認できるようになりました。今まで buildspec.yml を CodeBuild の実環境でトライ&エラーで修正した経験がある方もいらっしゃるのではないでしょうか。ローカルで実行できることでテスト実行や、記述に問題があった時のデバッグを簡単に行えます。
- AWS CodeBuild Now Supports Local Testing and Debugging
- Announcing Local Build Support for AWS CodeBuild
概要
AWS CodeBuild はビルド実行サービスです。アプリケーションのテストやビルド、必要に応じてビルドしたアプリケーションを S3 へアップロードすることができます。CodeBuild の処理内容は YAML ファイル(デフォルトはbuildspec.yml)に記述した内容に従って実行されます。(以降、このファイルをbuildspec.ymlを記載します)
今まで buildspec.yml は CodeBuild で実際に動かしてみるまで想定した動作をするのか分かりませんでした。また想定した動作をしない時に CloudWatch Logs にある程度のログ出力はされますが、状況によってはなぜ失敗したのかわからず、トライ&エラーを繰り返して解決するようなケースがありました。
今回のアップデートは CodeBuild をローカル環境で動作させることができる Docker Image が公開されました。DockerHub の Amazon のリポジトリで公開されています。
この Image を利用することでローカルで起動したコンテナ内で開発中のアプリケーションを buildspec.yml の内容に従って、テスト、ビルド、成果物の作成などを実行できます。つまり buildspec.yml の初回作成時や修正を実際に CodeBuild で動かす前にローカル環境でテスト、デバッグできることになります。
それでは早速試してみましょう。
試してみた
Python のウェブアプリケーションフレームワークの Django を使ったウェブアプリケーションを例に試してみます。
Django アプリケーションを本番環境(今回は EC2 とします)にデプロイする前に CodeBuild でテストして、テストに成功したら S3 にアーカイブファイルをアップロードするとします。もう少し具体的に書くと、依存ライブラリをインストール、テスト、必要ファイルのみを成果物としてアーカイブ、アップロードします。buildspec.yml を書くと以下のような感じでしょうか。
buildspec.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | version: 0.2phases: install: commands: - pip install -r requirements.txt build: commands: - python manage.py testartifacts: files: - app/* - project/* - manage.py - requirements.txt |
ローカル実行するには以下のような手順が必要です。
- ビルド用の Docker イメージ作成
- ビルド実行用の イメージのダウンロード
- ローカルでのビルド実行
実行環境
- OS : macOS High Sierra (v10.13.3)
- Docker : Docker E18.04.0-ce-mac62
ビルド用の Docker イメージ作成
buildspec.yml に従って処理を実行するコンテナのイメージを作成します。CodeBuild と同じように OS / Runtime / Version の組み合わせのイメージを作成する必要があります。イメージはパブリックなレジストリで公開されていませんが、イメージを作成する Dockerfile は GitHub リポジトリで提供されています。Dockerfile を取得します。
1 | $ git clone https://github.com/aws/aws-codebuild-docker-images.git |
Dockerfile は CodeBuild と同じように OS / Runtime / Version の組み合わせの種類があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | $ find aws-codebuild-docker-images -name Dockerfileaws-codebuild-docker-images/ubuntu/nodejs/6.3.1/Dockerfileaws-codebuild-docker-images/ubuntu/nodejs/7.0.0/Dockerfileaws-codebuild-docker-images/ubuntu/nodejs/4.4.7/Dockerfileaws-codebuild-docker-images/ubuntu/nodejs/4.3.2/Dockerfileaws-codebuild-docker-images/ubuntu/nodejs/8.11.0/Dockerfileaws-codebuild-docker-images/ubuntu/nodejs/5.12.0/Dockerfileaws-codebuild-docker-images/ubuntu/docker/1.12.1/Dockerfileaws-codebuild-docker-images/ubuntu/docker/17.09.0/Dockerfileaws-codebuild-docker-images/ubuntu/ubuntu-base/14.04/Dockerfileaws-codebuild-docker-images/ubuntu/python/3.3.6/Dockerfileaws-codebuild-docker-images/ubuntu/python/3.5.2/Dockerfileaws-codebuild-docker-images/ubuntu/python/2.7.12/Dockerfileaws-codebuild-docker-images/ubuntu/python/3.4.5/Dockerfileaws-codebuild-docker-images/ubuntu/golang/1.5.4/Dockerfileaws-codebuild-docker-images/ubuntu/golang/1.6.3/Dockerfileaws-codebuild-docker-images/ubuntu/golang/1.7.3/Dockerfileaws-codebuild-docker-images/ubuntu/golang/1.10/Dockerfileaws-codebuild-docker-images/ubuntu/java/openjdk-8/Dockerfileaws-codebuild-docker-images/ubuntu/java/openjdk-6/Dockerfileaws-codebuild-docker-images/ubuntu/java/openjdk-7/Dockerfileaws-codebuild-docker-images/ubuntu/java/openjdk-9/Dockerfileaws-codebuild-docker-images/ubuntu/php/5.6/Dockerfileaws-codebuild-docker-images/ubuntu/php/7.0/Dockerfileaws-codebuild-docker-images/ubuntu/dot-net/core-1/Dockerfileaws-codebuild-docker-images/ubuntu/dot-net/core-2/Dockerfileaws-codebuild-docker-images/ubuntu/android-java-7/24.4.1/Dockerfileaws-codebuild-docker-images/ubuntu/ruby/2.3.1/Dockerfileaws-codebuild-docker-images/ubuntu/ruby/2.2.5/Dockerfileaws-codebuild-docker-images/ubuntu/ruby/2.5.1/Dockerfileaws-codebuild-docker-images/ubuntu/ruby/2.1.10/Dockerfileaws-codebuild-docker-images/ubuntu/android-java-8/24.4.1/Dockerfileaws-codebuild-docker-images/ubuntu/android-java-8/26.1.1/Dockerfileaws-codebuild-docker-images/ubuntu/android-java-6/24.4.1/Dockerfile |
CodeBuild に設定したものと同じものを選びましょう。今回は Python 3 の最新版、Python 3.5.2 のイメージを作成します。なお、イメージを作成する前に Dockerfile の ENTRYPOINT を削除、もしくはコメントアウトする必要があります。
1 2 3 | $ cd aws-codebuild-docker-images/ubuntu/python/3.5.2/$ sed -ie 's/^ENTRYPOINT/#ENTRYPOINT/g' Dockerfile$ docker build -t aws/codebuild/python:3.5.2 . |
ビルドは結構時間かかります。これでイメージの作成は完了です。
ビルド実行用のイメージのダウンロード
ビルド用のコンテナを操作するエージェントがインストールされたイメージをダウンロードします。
1 | $ docker pull amazon/aws-codebuild-local:latest --disable-content-trust=false |
ローカルでのビルド実行
ローカルでビルドを実行します。docker runコマンドを実行するだけです。実行する際は三つの環境変数の指定が必要です。
- IMAGE_NAME : ビルドしたイメージの名前
- ARTIFACTS : アーカイブファイルの出力先ディレクトリ
- SOURCE : ビルドするアプリケーションのディレクトリ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | docker run \ -it -v /var/run/docker.sock:/var/run/docker.sock \ -e "IMAGE_NAME=aws/codebuild/python:3.5.2" \ -e "ARTIFACTS=/tmp" \ -e "SOURCE=/Users/fujimoto.shinji/python/django-rest" \ amazon/aws-codebuild-localRemoving agentresources_build_1 ... doneRemoving agentresources_agent_1 ... doneRemoving network agentresources_defaultRemoving volume agentresources_user_volumeRemoving volume agentresources_source_volumeCreating network "agentresources_default" with the default driverCreating volume "agentresources_user_volume" with local driverCreating volume "agentresources_source_volume" with local driverCreating agentresources_agent_1 ...Creating agentresources_agent_1 ... doneCreating agentresources_build_1 ...Creating agentresources_build_1 ... doneAttaching to agentresources_agent_1, agentresources_build_1build_1 | [Container] 2018/05/09 06:53:05 Waiting for agent pingbuild_1 | [Container] 2018/05/09 06:53:05 Waiting for DOWNLOAD_SOURCEbuild_1 | [Container] 2018/05/09 06:53:32 Phase is DOWNLOAD_SOURCEbuild_1 | [Container] 2018/05/09 06:53:34 CODEBUILD_SRC_DIR=/codebuild/output/src221564627/srcbuild_1 | [Container] 2018/05/09 06:53:34 YAML location is /codebuild/output/src221564627/src/buildspec.ymlbuild_1 | [Container] 2018/05/09 06:53:34 Processing environment variablesbuild_1 | [Container] 2018/05/09 06:53:34 Moving to directory /codebuild/output/src221564627/srcbuild_1 | [Container] 2018/05/09 06:53:34 Registering with agentbuild_1 | [Container] 2018/05/09 06:53:34 Phases found in YAML: 2build_1 | [Container] 2018/05/09 06:53:34 INSTALL: 1 commandsbuild_1 | [Container] 2018/05/09 06:53:34 BUILD: 1 commandsbuild_1 | [Container] 2018/05/09 06:53:34 [INSTALL BUILD UPLOAD_ARTIFACTS]build_1 | [Container] 2018/05/09 06:53:34 Phase complete: DOWNLOAD_SOURCE Success: truebuild_1 | [Container] 2018/05/09 06:53:34 Phase context status code: Message:build_1 | [Container] 2018/05/09 06:53:34 Entering phase INSTALLbuild_1 | [Container] 2018/05/09 06:53:34 Running command pip install -r requirements.txtbuild_1 | [Container] 2018/05/09 06:54:45 Phase complete: INSTALL Success: truebuild_1 | [Container] 2018/05/09 06:54:45 Phase context status code: Message:build_1 | [Container] 2018/05/09 06:54:46 Entering phase PRE_BUILDbuild_1 | [Container] 2018/05/09 06:54:46 Phase complete: PRE_BUILD Success: truebuild_1 | [Container] 2018/05/09 06:54:46 Phase context status code: Message:build_1 | [Container] 2018/05/09 06:54:46 Entering phase BUILDbuild_1 | [Container] 2018/05/09 06:54:46 Running command python manage.py testbuild_1 | [Container] 2018/05/09 06:54:48 Phase complete: BUILD Success: truebuild_1 | [Container] 2018/05/09 06:54:48 Phase context status code: Message:build_1 | [Container] 2018/05/09 06:54:48 Entering phase POST_BUILDbuild_1 | [Container] 2018/05/09 06:54:48 Phase complete: POST_BUILD Success: truebuild_1 | [Container] 2018/05/09 06:54:48 Phase context status code: Message:build_1 | [Container] 2018/05/09 06:54:48 Preparing to copy artifactsbuild_1 | [Container] 2018/05/09 06:54:48 Expanding base directory path: .build_1 | [Container] 2018/05/09 06:54:48 Assembling file listbuild_1 | [Container] 2018/05/09 06:54:48 Expanding .build_1 | [Container] 2018/05/09 06:54:48 Expanding artifact file paths for base directory .build_1 | [Container] 2018/05/09 06:54:48 Assembling file listbuild_1 | [Container] 2018/05/09 06:54:48 Expanding app/*build_1 | [Container] 2018/05/09 06:54:48 Expanding project/*build_1 | [Container] 2018/05/09 06:54:48 Expanding manage.pybuild_1 | [Container] 2018/05/09 06:54:48 Expanding requiments.txtbuild_1 | [Container] 2018/05/09 06:54:48 Skipping invalid artifact path requiments.txtbuild_1 | [Container] 2018/05/09 06:54:48 Found 14 file(s)build_1 | [Container] 2018/05/09 06:54:49 Phase complete: UPLOAD_ARTIFACTS Success: truebuild_1 | [Container] 2018/05/09 06:54:49 Phase context status code: Message:agentresources_build_1 exited with code 0 |
ビルド用コンテナがステータスコード 0 で終了していれば問題なく処理に成功しています。成功しても実行用コンテナは停止しないので Ctrl+c で終了します。アーカイブファイルも確認してみましょう。
1 2 3 4 5 | $ ls /tmp/artifacts.zip$ unzip -q /tmp/artifacts.zip$ lsapp manage.py project requirements.txt |
指定されたディレクトリ、ファイルだけがアーカイブされていますね。
まとめ
いかがでしたでしょうか? ローカルに Docker 実行環境が整っていれば簡単に実行できました。