Amazon CloudWatch Eventsを使ってDockerイメージをデイリービルドする

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは。齋藤です。

ネタ被り感がある(1, 2)のですが、今回は業務で必要になりそうだったので ブログを書きました。

CloudWatch Eventsが CodeBuildに 対応しました。 そこで、今日は CodeBuildとCloudWatch Eventsを組み合わせて Docker Imageをデイリーでビルドするようにしてみます。 デイリーでビルドすることで、常に最新のイメージが使えることになります。

次のような流れでセットアップしていきます。

  • Dockerfileを書く
  • CodeBuildの設定を書く
  • マネージメントコンソールからCodeBuildでビルドプロジェクトの設定をする
  • IAMのポリシーに設定を追加する
  • CloudWatchイベントの設定をする

AWSのCodeBuildを使って ECRやDockerHubに push するサンプルは公式ドキュメントにもあります。 内容としてはこちらをベースにやっていきます。

CodeBuildのビルドの入力としては S3、GitHub、CodeCommit、BitBucketと選べるのですが 今回は GitHubの個人アカウントを使うことにします。

最終的なリポジトリの最小構成としては以下のような形になりました。

$ tree
.
├── Dockerfile
└── buildspec.yml

今回ローカルでは次のような環境で動かしましたが 基本的には Dockerコンテナの上でビルドをします。

$ docker version
Client:
 Version:      17.09.1-ce
 API version:  1.32
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:22:25 2017
 OS/Arch:      darwin/amd64

Server:
 Version:      17.09.1-ce
 API version:  1.32 (minimum version 1.12)
 Go version:   go1.8.3
 Git commit:   19e2cf6
 Built:        Thu Dec  7 22:28:28 2017
 OS/Arch:      linux/amd64
 Experimental: true

また、今回は ECRのリポジトリが存在する前提で話を進めさせていただきます。ご了承ください。

Dockerfileを書きます

次のようなDockerfileを用意しました。 openjdk:8-jdk-alpine を ベースに git と ssh を追加するイメージです。

FROM openjdk:8-jdk-alpine

RUN apk add --no-cache \
        openssh \
        git

特に凝ったことはしてませんね。 このファイルをルートディレクトリに置いておきます。 次のコマンドで、イメージをローカルでビルドして ビルドが失敗しないかだけ確認しておきましょう。

docker build -t .

CodeBuildの設定を書く

CodeBuildでは ビルドの設定をymlで記述することが可能です。 次のような設定ファイル buildspec.yml を用意しておきます。

version: 0.1
phases:
  pre_build: # ecrにログイン
    commands:
      - echo Logging in to Amazon ECR...
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email) # docker のバージョンによって --no-include-emailが必要
  build: # イメージのビルドとタグ付け
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...          
      - docker build -t $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: # イメージの push
    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

上記で用意した設定ファイルではいくつかの環境変数を用いています。

  • $AWS_DEFAULT_REGION: ECRのリポジトリがあるリージョン
  • $IMAGE_REPO_NAME: ECRのリポジトリ名
  • $IMAGE_TAG: イメージのタグ名
  • $AWS_ACCOUNT_ID: AWSアカウントのID

上記の環境変数は、CodeBuildで ビルドプロジェクトの設定の際に必要になります。

CodeBuildでビルドプロジェクトの設定をする

今回はマネージメントコンソールから CodeBuildの設定をしてみます。

まずは CodeBuildの次のような画面に飛んで、「プロジェクトの作成」ボタンを押します。 初めての方は別の画面が出るかもしれません。

ビルドプロジェクト名の設定と リポジトリの連携

ビルドプロジェクトの名前を入力したら GitHubを選択します。

GitHubを選択したら、初めての場合、OAuth2での連携をするためのボタンが表示されます。 このボタンを押して、出てきたウィンドウを進めて連携をします。

何はともあれ、連携が終わったら、リポジトリの選択を行います。 ここでは事前に用意しておいた「codebuild-sample」を選びました。

また、コミット時のWebHookによるビルドも行いたいので 「コードの変更がレポジトリにプッシュされるたびに再構築する」のチェックを入れておきます。

ビルド環境の設定

今度は ビルド環境の設定です。

大体デフォルトの設定ですが、次のような設定をしておきます。

CodeBuildで用意されているイメージは awscliや所定のコマンドが入っており便利です。

今回は Dockerのイメージのビルドをするので

aws/codebuild/Docker:17.09.0 のイメージを使います。

この画面で buildspec.yml相当の記述も出来ますが 今回は 事前に準備しているので、単に buildspec.ymlを使うようにします。

ビルド時の IAM roleの設定

ビルド時の IAM Roleの設定を行います。

コンソールでIAM Roleを作ってくれるので、これを使います。 しかし、今回はビルドでECR に pushするので設定を追加しないとビルドがエラーになります。 この設定は後で追加します。

ビルド時の環境変数の設定

今度は環境変数の設定です。

やりました。 再掲しておきます。

  • $AWS_DEFAULT_REGION: ECRのリポジトリがあるリージョン
  • $IMAGE_REPO_NAME: ECRのリポジトリ名
  • $IMAGE_TAG: イメージのタグ名
  • $AWS_ACCOUNT_ID: AWSアカウントのID

これでビルドのプロジェクトの作成は終了です

最後に「続行」ボタンを押した後、確認画面が出ます。

「保存してビルド」を押下します。すると次のような画面に飛ぶので 「ビルドの開始」を押下します。

ここでは、設定したポリシーに ECR に ログインする権限がないので エラーになると思います。

IAM Roleに ECRの設定を追加する

こちらの内容は 公式ドキュメントにも書いております。

IAM Roleの画面に飛んで設定を追加しておきましょう。

再度、CodeBuildで「ビルドの開始」を行うとECRへの ログインに成功してイメージのビルド、pushに成功するはずです。

CloudWatch イベントの設定を追加して、デイリービルドするようにする

CodeBuildのARNの指定方法はいくつか指定方法がありますが 今回は単純にプロジェクトのビルドをやっていきますので 次のような形になります。

arn:aws:codebuild:region-ID:account-ID:project/project-name

と言うわけで次のようなARNを設定しました。

arn:aws:codebuild:ap-northeast-1:<your-account-id>:project/codebuild-test2

今回はcron式でのスケジューリング指定をしました。次のような式になります。

0 0 */1 * ? *

CloudWatch Eventsの設定は前提で見るとこんな感じ。

設定をすると、指定の時間に次のようなビルドが走ります。 (画像はイメージです。今回ブログで設定した物とは別の名前の似たような設定の物の画像です。)

まとめ

今回はコンソールから、CloudWatchイベントのスケジューリングイベントを使って Dockerイメージをビルドするような設定をしてみました。

便利ですね。以前の記事と同じ内容では Dockerのバージョンが新しくなったためか、ECRへのログインが失敗しました。 docker のバージョンによって --no-include-emailが必要なことに注意してください。

Happy Hacking!!

参考

  • http://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/sample-docker.html
  • https://qiita.com/nagais/items/b60824274d9ca724dea7
  • https://dev.classmethod.jp/tool/docker/20170225-codebuild-docker/