CodeBuildで独自イメージを使ってビルドする

# 概要

(2019年4月18日 更新)

- OracleJDKをOpenJDKに変更しました。
- Gradle5.xだとビルドエラーになる場合があるので、Gradle4.10.3に設定しました。
- DockerHubにコンテナイメージを配置しました。[こちら](https://hub.docker.com/r/akikinyan/springboot-build)からどうぞ。

--- 

Spring Boot2.xでGradleを使う場合は、Gradle4.x以上が必要となる。
AWSで用意されているJavaのDockerイメージは、```Apache Maven 3.3.3、Apache Ant 1.9.6、Gradle 2.7```となっているため、gradleをアップデートインストールしないと、ビルドが出来ない。

毎回インストールしても良いのだが、5分ほど時間がかかってしまう。（後述）
そのため、独自のDockerイメージを使ってビルドにチャレンジしてみました。

AWS CodeBuild に用意されている Docker イメージ
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/build-env-ref-available.html


AWSのイメージを使ってgradleのバージョンアップをする方法も載せておきます。

```
phases:
  install:
    commands:
     - echo Entered the install phase...
     - add-apt-repository ppa:cwchien/gradle
     - apt-get update -y
     - apt-get install -y gradle
     - gradle -v
```

# 手順

ざっくり書くとこんな感じ。

1. ビルド用のDockerコンテナイメージを作る
1. ECRにコンテナイメージをアップロードする
1. ECRのリポジトリにCodeBuildからアクセス出来るよう権限を設定する
1. CodeBuildの設定を行う
1. ビルド実行

## コンテナイメージの作成

お好みで良いと思いますが、今回はubuntuイメージを使ってみます。
色々と使い回しができるように、Docker、Maven、Ant、Gitコマンドも使えるように、追加でインストールしておきます。

```text:Dockerfile
FROM ubuntu:latest

# base update
RUN apt-get update && apt-get upgrade -y

# add-apt-repository コマンドの追加
RUN apt-get install -y apt-file
RUN apt-file update
RUN apt-file search add-apt-repository
RUN apt-get install -y software-properties-common

# gradle & java 追加
RUN add-apt-repository ppa:cwchien/gradle
RUN add-apt-repository ppa:webupd8team/java

# インストール
RUN apt-get update && apt-get upgrade -y gradle git maven ant

# OracleJDKのインストール
# RUN echo debconf shared/accepted-oracle-license-v1-1 select true | debconf-set-selections
# RUN echo debconf shared/accepted-oracle-license-v1-1 seen true | debconf-set-selections
# RUN apt-get install -y oracle-java8-installer

# OpenJDKのインストール && 1.8.0の切り替え
RUN apt-get install -y openjdk-8-jdk
RUN update-java-alternatives --set java-1.8.0-openjdk-amd64

# Graldeのダウングレード
RUN apt-get install -y gradle-4.10.3
RUN update-alternatives --set gradle /usr/lib/gradle/4.10.3/bin/gradle
```



## ECRにコンテナイメージをアップロードする

事前にAmazon ECRにリポジトリを作成しておきます。（手順は割愛します）

リポジトリを作成後、コマンド例に従ってECRにPushを行います。

コマンド例

```
aws ecr get-login --no-include-email --region ap-northeast-1
docker build -t [リポジトリ名] .
docker tag springboot-build:latest xxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/[REPOSITORY]:[TAG]
docker push xxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/[REPOSITORY]:[TAG]
```

私の作成済みイメージを使う場合は

```
aws ecr get-login --no-include-email --region ap-northeast-1
docker pull akikinyan/springboot-build:latest
docker tag akikinyan/springboot-build:latest xxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/[REPOSITORY]:[TAG]
docker push xxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/[REPOSITORY]:[TAG]
```


## ECRのリポジトリにCodeBuildからアクセス出来るよう権限を設定する

Amazon ECR -> リポジトリの対象となるリポジトリに、アクセス権を設定する。
参考となる手順は、以下にあります。

AWS CodeBuild の Amazon ECR サンプル
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-ecr.html

ポリシードキュメント

```
{
    "Version": "2008-10-17",
    "Statement": [
        {
            "Sid": "CodeBuildAccess",
            "Effect": "Allow",
            "Principal": {
                "Service": "codebuild.amazonaws.com"
            },
            "Action": [
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "ecr:BatchCheckLayerAvailability"
            ]
        }
    ]
}
```

## CodeBuildの設定を行う

CodeBuildの「環境: ビルド方法」で、上記で作成したコンテナイメージを利用するように設定します。

|設定項目|設定内容|
|:------|:-----|
|環境イメージ|Docker イメージの指定|
|環境タイプ|Linux|
|カスタムイメージタイプ|Amazon ECR|
|Amazon ECR レポジトリ|作成したリポジトリ名|
|Amazon ECR イメージ|作成したタグ名|
|ビルド仕様|ソースコードのルートディレクトリの buildspec.yml を使用|
|buildspec名|buildspec.yml|


ビルド仕様はお好みで良いですが、buildspec.ymlのサンプルを載せておきます。

```yaml:buildspec.yml
version: 0.2

env:
  variables:
    JAVA_HOME: "/usr/lib/jvm/java-8-oracle"
      
phases:
  install:
    commands:
      - gradle -v
  build:
    commands:
      - gradle build -x test

artifacts:
  files:
    - ./build/libs/spring-boot-test-1.0.0.jar

```

## ビルド実行

CodeBuildからビルドを指示します。
（簡単なので割愛します）


## Q&A

Q. PROVISIONING phaseでClient Errorが出る

A. ECRのアクセス権が設定されていない

Unable to pull customer's container image. ErrorCode: 404 ~~~~
https://stackoverflow.com/questions/45079013/i-got-some-aws-codebuild-error-i-have-no-clue-to-solve-it