ようへいの日々精進XP

よかろうもん

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

追記 (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

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

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 イメージの取得 (作成)

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

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 って裏っかわでこんなことやってんだー, 多分」みたいな気分になってワクワクしつつ, オリジナルのコンテナイメージも普通に利用出来るかもしれないと思ったりした.

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