追記 (2018/05/05)

オリジナルのコンテナイメージも普通に利用出来るかもしれないと思ったりした.

普通に利用することが出来た.

以下のような Dockerfile を利用して, コンテナイメージを用意した上で CodeBuild を実行すると, ビルドが動いたことを確認した.

$ cat Dockerfile
FROM python:3
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

# コンテナイメージをビルド
$ docker build -t aws/codebuild/python:3.6.4 .

# CodeBuild Local を実行
$ docker run -it -v /var/run/docker.sock:/var/run/docker.sock  \
   -e "IMAGE_NAME=aws/codebuild/python:3.6.4"   \
   -e "ARTIFACTS=/tmp"   \
   -e "SOURCE=/path/to/sandbox/shunit2-with-moto-sample"  
   amazon/aws-codebuild-local

...
build_1  | [Container] 2018/05/05 00:03:30 Entering phase BUILD
build_1  | [Container] 2018/05/05 00:03:30 Running command invoke shunit
build_1  | [Container] 2018/05/05 00:03:32 Running command invoke unittest
build_1  | [Container] 2018/05/05 00:03:34 Phase complete: BUILD Success: true

...

LGTM, LGTM.

tl;dr

トゥイッターのタイムラインを眺めていたら, 以下のようなブログポストの情報が流れてきた.

Today, we’re excited to announce local build support in AWS CodeBuild. AWS CodeBuild is a fully managed build service. There are no servers to provision and scale, or software to install, configure, and operate. You just specify the location ...

aws.amazon.com

AWS CodeBuild がローカル環境でのビルドをサポートしたとのことなので, ざっくりと試してみることにした.

環境

$ cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.4 LTS"

$ docker --version
Docker version 1.12.0, build 8eab29e

ちなみに, コードスニペット内での $ は特に但し書きが無い場合には, ローカル環境 (Ubuntu) の Bash プロンプトとなる.

ローカル環境で AWS CodeBuild

メリット

冒頭で紹介したブログの冒頭にも (こんな事が出来るぜ的な文脈で書かれている) 書かれているけど, AWS CodeBuild をローカルで実行出来るメリットとしては…

  • buildspec.yml の整合性, 内容をローカルでチェック出来る
  • リポジトリにコミットする前に手元の環境でテスト (ビルド) が出来る
  • ↑ が出来ることで, ローカルの開発環境において, エラーを特定して修正出来る

が挙げられると思う.

ということで, CodeBuild 用 Dokcer イメージの取得 (作成)

まずは, 以下のリポジトリからソースコードを取得してくる.

aws-codebuild-docker-images - Official AWS CodeBuild repository for managed Docker images http://docs.aws.amazon.com/codebuild/latest/userguide/build-env-ref.html

github.com

取得は普通に git clone してくるだけ.

$ git clone https://github.com/aws/aws-codebuild-docker-images.git

取得したファイルを確認.

$ tree -L 2 aws-codebuild-docker-images
aws-codebuild-docker-images
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── NOTICE.txt
├── README.md
├── buildspec.yml
├── local_builds
│   ├── LICENSE.txt
│   └── README.md
└── ubuntu
    ├── android-java-6
    ├── android-java-7
    ├── android-java-8
    ├── docker
    ├── dot-net
    ├── golang
    ├── java
    ├── nodejs
    ├── php
    ├── python
    ├── ruby
    └── ubuntu-base

注目したいのは, ubuntu ディレクトリ以下のファイル群. どうやら, CodeBuild で通常サポートされているコンテナ環境の Dockerfile が提供されているようだ. 例えば, python ディレクトリ以下は, 以下のような構成となっている.

$ tree -L 2 aws-codebuild-docker-images/ubuntu/python
aws-codebuild-docker-images/ubuntu/python
├── 2.7.12
│   ├── Dockerfile
│   └── dockerd-entrypoint.sh
├── 3.3.6
│   ├── Dockerfile
│   └── dockerd-entrypoint.sh
├── 3.4.5
│   ├── Dockerfile
│   └── dockerd-entrypoint.sh
└── 3.5.2
    ├── Dockerfile
    └── dockerd-entrypoint.sh

4 directories, 8 files

ということで, いくつかのコンテナ環境の中から, 今回は Python 環境を利用してみることにする.

ローカル CodeBuild の Python 環境の準備

ブログによると,

Edit the Dockerfile to remove the last line ENTRYPOINT [“dockerd-entrypoint.sh”] and save the file.

とあるので, Dockerfile を少し修正する.

$ cd aws-codebuild-docker-images/ubuntu/python/3.5.2/
$ vim Dockerfile

Dockerfile の最後に書かれている, 以下の記述をコメントアウトする.

ENTRYPOINT ["dockerd-entrypoint.sh"]
↓
コメントアウト
↓
# ENTRYPOINT ["dockerd-entrypoint.sh"]

修正したら, 以下のようにコンテナイメージをビルドする.

$ docker build -t aws/codebuild/python:3.5.2 .

ビルドには時間がかかるので, しばし Twitter でも見ながら待つ.

CodeBuild local agent のセットアップ

CodeBuild をローカル環境で動かす為に, CodeBuild local agent というツールが提供されているので, これを pull しておく. この CodeBuild local agent が CodeBuild をローカル環境で実行する為に重要なツールになるんだと思う.

$ docker pull amazon/aws-codebuild-local:latest --disable-content-trust=false

出来立てホヤホヤ感がある.

$ docker images | grep aws-codebuild-local
amazon/aws-codebuild-local                      latest              8e99ddbed971        26 hours ago        352.1 MB

サンプルアプリケーションをビルドしてみる

せっかくなので, こちらのブログで書いたサンプルアプリケーション (shUnit2 云々) をビルド (テスト) してみたいので, 以下のように clone しておく.

$ git clone https://github.com/inokappa/shunit2-with-moto-sample.git

あとは, 以下のようにアプリケーションをビルドするだけ.

$ 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=/path/to/shunit2-with-moto-sample" \
  amazon/aws-codebuild-local

ビルド実行時に必要なオプションは以下の 3 つで, -e オプションで環境変数として与える.

環境変数 説明
IMAGE_NAME 先にビルドしておいた環境のコンテナイメージ (今回だと aws/codebuild/python:3.5.2 )
SOURCE ビルドしたいアプリケーションを展開したパス
ARTIFACTS 成果物を出力するディレクトリのパス

実行結果は以下のように出力された.

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/04 23:40:48 Waiting for agent ping
build_1  | [Container] 2018/05/04 23:40:48 Waiting for DOWNLOAD_SOURCE
build_1  | [Container] 2018/05/04 23:40:48 Phase is DOWNLOAD_SOURCE
build_1  | [Container] 2018/05/04 23:40:48 CODEBUILD_SRC_DIR=/codebuild/output/src642296205/src
build_1  | [Container] 2018/05/04 23:40:48 YAML location is /codebuild/output/src642296205/src/buildspec.yml
build_1  | [Container] 2018/05/04 23:40:48 Processing environment variables
build_1  | [Container] 2018/05/04 23:40:48 Moving to directory /codebuild/output/src642296205/src
build_1  | [Container] 2018/05/04 23:40:48 Registering with agent
build_1  | [Container] 2018/05/04 23:40:48 Phases found in YAML: 2
build_1  | [Container] 2018/05/04 23:40:48  PRE_BUILD: 4 commands
build_1  | [Container] 2018/05/04 23:40:48  BUILD: 2 commands
build_1  | [Container] 2018/05/04 23:40:48 [PRE_BUILD BUILD]
build_1  | [Container] 2018/05/04 23:40:48 Phase complete: DOWNLOAD_SOURCE Success: true
build_1  | [Container] 2018/05/04 23:40:48 Phase context status code:  Message: 
build_1  | [Container] 2018/05/04 23:40:48 Entering phase INSTALL
build_1  | [Container] 2018/05/04 23:40:48 Phase complete: INSTALL Success: true
build_1  | [Container] 2018/05/04 23:40:48 Phase context status code:  Message: 
build_1  | [Container] 2018/05/04 23:40:48 Entering phase PRE_BUILD
build_1  | [Container] 2018/05/04 23:40:48 Running command pip install -r requirements.txt
build_1  | [Container] 2018/05/04 23:41:31 Running command aws configure set default.region ap-northeast-1
build_1  | [Container] 2018/05/04 23:41:32 Running command aws configure set aws_access_key_id ''
build_1  | [Container] 2018/05/04 23:41:33 Running command aws configure set aws_secret_access_key ''
build_1  | [Container] 2018/05/04 23:41:33 Phase complete: PRE_BUILD Success: true
build_1  | [Container] 2018/05/04 23:41:33 Phase context status code:  Message: 
build_1  | [Container] 2018/05/04 23:41:33 Entering phase BUILD
build_1  | [Container] 2018/05/04 23:41:33 Running command invoke shunit
build_1  | [Container] 2018/05/04 23:41:38 Running command invoke unittest
build_1  | [Container] 2018/05/04 23:41:39 Phase complete: BUILD Success: true
build_1  | [Container] 2018/05/04 23:41:39 Phase context status code:  Message: 
build_1  | [Container] 2018/05/04 23:41:39 Entering phase POST_BUILD
build_1  | [Container] 2018/05/04 23:41:39 Phase complete: POST_BUILD Success: true
build_1  | [Container] 2018/05/04 23:41:39 Phase context status code:  Message

一応, Phase complete: BUILD Success: true と出力されているので, ビルド (テスト) は行われていることを確認した. 尚, Ctrl + c でプロンプトに戻る (Graceful Stop する)ことが出来る.

ちなみに, サンプルアプリケーションはオリジナルの Docker イメージの利用を想定していたので, 当初はビルドに必要な Python モジュールがインストールされていない状態だった為にビルドに失敗した… ということで, 以下のように buildspec.yml に pip install -r requirements.txt を追加した.

version: 0.2

env:
  variables:
    TERM: "xterm"
    _ENV: "test"

phases:
  pre_build:
    commands:
      - pip install -r requirements.txt
      - aws configure set default.region ap-northeast-1
      - aws configure set aws_access_key_id ''
      - aws configure set aws_secret_access_key ''
  build:
    commands:
      - invoke shunit
      - invoke unittest

また, ビルド (テスト) に失敗した際には以下のように出力された (一部抜粋).

...
build_1  | [Container] 2018/05/04 23:46:06 Entering phase BUILD
build_1  | [Container] 2018/05/04 23:46:06 Running command invoke shunit
build_1  | [Container] 2018/05/04 23:46:08 Command did not exit successfully invoke shunit exit status 1
build_1  | [Container] 2018/05/04 23:46:08 Phase complete: BUILD Success: false
build_1  | [Container] 2018/05/04 23:46:08 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: invoke shunit. Reason: exit status 1
build_1  | [Container] 2018/05/04 23:46:08 Entering phase POST_BUILD
build_1  | [Container] 2018/05/04 23:46:08 Phase complete: POST_BUILD Success: true
build_1  | [Container] 2018/05/04 23:46:08 Phase context status code:  Message: 

一応, ビルドが失敗したことは把握出来ると思う.

以上

簡単に AWS CodeBuild をローカル環境で実行出来ることを確認してみた. Docker 環境さえ手元にあれば, とても簡単に試すことが出来ると思う. また, 「あー, CodeBuild って裏っかわでこんなことやってんだー, 多分」みたいな気分になってワクワクしつつ, オリジナルのコンテナイメージも普通に利用出来るかもしれないと思ったりした.

以上, 現場からの報告でした.

元記事はこちら

2018-05-05ゴールデンウィークスペシャル : AWS CodeBuild がローカル環境での実行をサポートしているとのことなので, ざっくりと試してみた