SpringBootをCodeBuildでビルドしてECRにPUSHする!

今回はこのような質問をいただきました。

SpringBootをCodeBuildでビルドしたい!
CodeBuildならJenkinsやCircleCIを使わずにAWSの機能だけで完結するので良いですね。
そこで今回はこちらの質問について解説していきます!
- AWS
- CodeBuild
- CodeCommit
- ECR
- IAM
- SpringBoot
- Kotlin
- Java 11
CodeCommitリポジトリの作成!
まずはSpringBootプロジェクトを配置するCodeCommitリポジトリを作成します。
以下の記事を参考に作成してみてください。

作成したらSpringBootプロジェクトをプッシュしておきます。
GitHubでSpringBootのコードを管理している方はこちらの方法でCodeCommitにミラーリングもできます。

ECRリポジトリの作成!
次にビルドしたイメージを配置するECRリポジトリを作成します。
Repositories→リポジトリの作成へと進みます。

任意の名前を入力して作成します。

以下の項目は無効のままで問題ありません。
- アクセスとタグ:タグのイミュータビリティ
- イメージスキャンの設定:プッシュ時にスキャン
- 暗号化設定:KMS 暗号化

これでECRの準備は完了です。
CodeBuildの準備!
CodeBuildのビルドプロジェクトを作成する前に以下の2つのファイルを用意しておきます。
どちらもSpringBootプロジェクトのルートディレクトリに配置しておきます。
- Dockerfile
- buildspec.yml
Dockerfileの準備
今回はJava11を使うのでadoptopenjdkを使います。
JAR_FILEにはSpringBootをビルドしたファイルを指定してください。
FROM adoptopenjdk/openjdk11:alpine-slim
EXPOSE 8080
ARG JAR_FILE=sample-0.0.1-SNAPSHOT.jar
ADD ./build/libs/${JAR_FILE} /application.jar
ENTRYPOINT java -Dfile.encoding=UTF-8 -jar /application.jar
buildspec.ymlの準備
buildspec.ymlはCodeBuildのビルド手順書みたいなものです。
このファイル通りにコマンドを実行してくれます。
SpringBootをビルドするためにruntime-versionsにopenjdk11を指定しています。
あとは
ECRにログイン→SpringBootビルド→docker build→ECRにプッシュ
といった流れです。
環境変数はCodeBuild側で設定します。
version: 0.2
phases:
install:
runtime-versions:
java: openjdk11
pre_build:
commands:
- echo Logging in to Amazon ECR...
- $(aws ecr get-login --no-include-email --region $AWS_DEFAULT_REGION)
build:
commands:
- echo Build started on `date`
- echo Building the SpringBoot project...
- ./gradlew build -x test
- echo Building the Docker image...
- IMAGE_TAG=$(date '+%Y%m%d.%H%M%S.%N')
- docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
- echo docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
- docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
post_build:
commands:
- echo Build completed on `date`
- echo Pushing the Docker image...
- docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
この2つのファイルをCodeCommitにプッシュしておきましょう。
CodeBuildの作成!
CodeBuildのビルドプロジェクトを作成します。
CodeBuild→ビルドプロジェクトを作成すると進みます。

任意のプロジェクト名を設定します。

ソースは先ほど作成したCodeCommitを指定しましょう。
リファレンスタイプはDockerfileとbuildspec.ymlが含まれていれば何でも良いです。

環境は以下のように設定します。
- 環境イメージ:マネージド型イメージ
- オペレーティングシステム:Ubuntu
- ランタイム:Standard
- イメージ:aws/codebuild/standard:3.0
- イメージのバージョン:このランタイムバージョンには常に…
- 環境タイプ:Linux
- 特権付与:✔
- サービスロール:新しいサービスロール
- ロール名:codebuild-sample-service-role(初期値)
イメージはaws/codebuild/standard:3.0を選択しないとbuildspec.ymlで設定したruntime-versions:openjdk11が使えなくなってしまうので注意してください。
特権付与はdockerコマンドを使うために有効化します。
新しく作成したサービスロールは後ほど追加で権限を付与するため、覚えておいてください。

環境の追加設定から環境変数を設定します。
buildspec.ymlの環境変数ですね。
以下の3つを登録してください。
- AWS_ACCOUNT_ID:アカウントID(数値)
- IMAGE_REPO_NAME:ECRのリポジトリ名
- AWS_DEFAULT_REGION:リージョン(東京はap-northeast-1)

コンピューティングは最小の3 GB メモリ、2 vCPUを選んでおけば、月100分は無料みたいです。
残りの設定はデフォルトで良いと思います。
今回はサンプルのため、私はログのCloudWatch Logs – オプショナルのチェックを外しておきました。
設定が完了したら作成します。
サービスロールにECRを操作する権限を付与する!
このままだとCodeBuildからECRを操作できないため、権限を付与します。
IAM→ロールと進み、先ほど作成したロールを選択します。

「ポリシーをアタッチします」から以下のポリシーをアタッチします。
- AmazonEC2ContainerRegistryPowerUser
これですべての準備ができました。
CodeBuildでビルドしてみましょう!
最後にCodeBuildでビルド!
先ほど作成したビルドプロジェクトからビルドの開始を選択します。

ビルドの設定を変更できますが、そのままビルドを開始しましょう。
ステータスが成功となればECRにプッシュされているはずです!

あとがき
結構時間かかりましたが、とりあえずCodeBuildでビルドすることができました。
buildspec.ymlでruntime-versionsを設定できることに気づくのに時間がかかりました。
せっかくビルドしたので今度はECSにデプロイしたいですね!