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
version: 0.2 phases: install: commands: - pip install -r requirements.txt build: commands: - python manage.py test artifacts: 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 を取得します。
$ git clone https://github.com/aws/aws-codebuild-docker-images.git
Dockerfile は CodeBuild と同じように OS / Runtime / Version の組み合わせの種類があります。
$ find aws-codebuild-docker-images -name Dockerfile aws-codebuild-docker-images/ubuntu/nodejs/6.3.1/Dockerfile aws-codebuild-docker-images/ubuntu/nodejs/7.0.0/Dockerfile aws-codebuild-docker-images/ubuntu/nodejs/4.4.7/Dockerfile aws-codebuild-docker-images/ubuntu/nodejs/4.3.2/Dockerfile aws-codebuild-docker-images/ubuntu/nodejs/8.11.0/Dockerfile aws-codebuild-docker-images/ubuntu/nodejs/5.12.0/Dockerfile aws-codebuild-docker-images/ubuntu/docker/1.12.1/Dockerfile aws-codebuild-docker-images/ubuntu/docker/17.09.0/Dockerfile aws-codebuild-docker-images/ubuntu/ubuntu-base/14.04/Dockerfile aws-codebuild-docker-images/ubuntu/python/3.3.6/Dockerfile aws-codebuild-docker-images/ubuntu/python/3.5.2/Dockerfile aws-codebuild-docker-images/ubuntu/python/2.7.12/Dockerfile aws-codebuild-docker-images/ubuntu/python/3.4.5/Dockerfile aws-codebuild-docker-images/ubuntu/golang/1.5.4/Dockerfile aws-codebuild-docker-images/ubuntu/golang/1.6.3/Dockerfile aws-codebuild-docker-images/ubuntu/golang/1.7.3/Dockerfile aws-codebuild-docker-images/ubuntu/golang/1.10/Dockerfile aws-codebuild-docker-images/ubuntu/java/openjdk-8/Dockerfile aws-codebuild-docker-images/ubuntu/java/openjdk-6/Dockerfile aws-codebuild-docker-images/ubuntu/java/openjdk-7/Dockerfile aws-codebuild-docker-images/ubuntu/java/openjdk-9/Dockerfile aws-codebuild-docker-images/ubuntu/php/5.6/Dockerfile aws-codebuild-docker-images/ubuntu/php/7.0/Dockerfile aws-codebuild-docker-images/ubuntu/dot-net/core-1/Dockerfile aws-codebuild-docker-images/ubuntu/dot-net/core-2/Dockerfile aws-codebuild-docker-images/ubuntu/android-java-7/24.4.1/Dockerfile aws-codebuild-docker-images/ubuntu/ruby/2.3.1/Dockerfile aws-codebuild-docker-images/ubuntu/ruby/2.2.5/Dockerfile aws-codebuild-docker-images/ubuntu/ruby/2.5.1/Dockerfile aws-codebuild-docker-images/ubuntu/ruby/2.1.10/Dockerfile aws-codebuild-docker-images/ubuntu/android-java-8/24.4.1/Dockerfile aws-codebuild-docker-images/ubuntu/android-java-8/26.1.1/Dockerfile aws-codebuild-docker-images/ubuntu/android-java-6/24.4.1/Dockerfile
CodeBuild に設定したものと同じものを選びましょう。今回は Python 3 の最新版、Python 3.5.2 のイメージを作成します。なお、イメージを作成する前に Dockerfile の ENTRYPOINT を削除、もしくはコメントアウトする必要があります。
$ 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 .
ビルドは結構時間かかります。これでイメージの作成は完了です。
ビルド実行用のイメージのダウンロード
ビルド用のコンテナを操作するエージェントがインストールされたイメージをダウンロードします。
$ docker pull amazon/aws-codebuild-local:latest --disable-content-trust=false
ローカルでのビルド実行
ローカルでビルドを実行します。docker run
コマンドを実行するだけです。実行する際は三つの環境変数の指定が必要です。
- IMAGE_NAME : ビルドしたイメージの名前
- ARTIFACTS : アーカイブファイルの出力先ディレクトリ
- SOURCE : ビルドするアプリケーションのディレクトリ
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-local Removing agentresources_build_1 ... done Removing agentresources_agent_1 ... done Removing network agentresources_default Removing volume agentresources_user_volume Removing volume agentresources_source_volume Creating network "agentresources_default" with the default driver Creating volume "agentresources_user_volume" with local driver Creating volume "agentresources_source_volume" with local driver Creating agentresources_agent_1 ... Creating agentresources_agent_1 ... done Creating agentresources_build_1 ... Creating agentresources_build_1 ... done Attaching to agentresources_agent_1, agentresources_build_1 build_1 | [Container] 2018/05/09 06:53:05 Waiting for agent ping build_1 | [Container] 2018/05/09 06:53:05 Waiting for DOWNLOAD_SOURCE build_1 | [Container] 2018/05/09 06:53:32 Phase is DOWNLOAD_SOURCE build_1 | [Container] 2018/05/09 06:53:34 CODEBUILD_SRC_DIR=/codebuild/output/src221564627/src build_1 | [Container] 2018/05/09 06:53:34 YAML location is /codebuild/output/src221564627/src/buildspec.yml build_1 | [Container] 2018/05/09 06:53:34 Processing environment variables build_1 | [Container] 2018/05/09 06:53:34 Moving to directory /codebuild/output/src221564627/src build_1 | [Container] 2018/05/09 06:53:34 Registering with agent build_1 | [Container] 2018/05/09 06:53:34 Phases found in YAML: 2 build_1 | [Container] 2018/05/09 06:53:34 INSTALL: 1 commands build_1 | [Container] 2018/05/09 06:53:34 BUILD: 1 commands build_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: true build_1 | [Container] 2018/05/09 06:53:34 Phase context status code: Message: build_1 | [Container] 2018/05/09 06:53:34 Entering phase INSTALL build_1 | [Container] 2018/05/09 06:53:34 Running command pip install -r requirements.txt build_1 | [Container] 2018/05/09 06:54:45 Phase complete: INSTALL Success: true build_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_BUILD build_1 | [Container] 2018/05/09 06:54:46 Phase complete: PRE_BUILD Success: true build_1 | [Container] 2018/05/09 06:54:46 Phase context status code: Message: build_1 | [Container] 2018/05/09 06:54:46 Entering phase BUILD build_1 | [Container] 2018/05/09 06:54:46 Running command python manage.py test build_1 | [Container] 2018/05/09 06:54:48 Phase complete: BUILD Success: true build_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_BUILD build_1 | [Container] 2018/05/09 06:54:48 Phase complete: POST_BUILD Success: true build_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 artifacts build_1 | [Container] 2018/05/09 06:54:48 Expanding base directory path: . build_1 | [Container] 2018/05/09 06:54:48 Assembling file list build_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 list build_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.py build_1 | [Container] 2018/05/09 06:54:48 Expanding requiments.txt build_1 | [Container] 2018/05/09 06:54:48 Skipping invalid artifact path requiments.txt build_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: true build_1 | [Container] 2018/05/09 06:54:49 Phase context status code: Message: agentresources_build_1 exited with code 0
ビルド用コンテナがステータスコード 0 で終了していれば問題なく処理に成功しています。成功しても実行用コンテナは停止しないので Ctrl+c
で終了します。アーカイブファイルも確認してみましょう。
$ ls /tmp/ artifacts.zip $ unzip -q /tmp/artifacts.zip $ ls app manage.py project requirements.txt
指定されたディレクトリ、ファイルだけがアーカイブされていますね。
まとめ
いかがでしたでしょうか? ローカルに Docker 実行環境が整っていれば簡単に実行できました。