0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

CodePipelineからFargate(ECS)にデプロイする(2/2) - 実装編

Last updated at Posted at 2019-12-13

はじめに

前回は準備編としてサンプルアプリケーションを作成し、コンテナイメージ化、
ECS Fargate構成にデプロイして動作確認を行うところまで実施しました。

今回は実際にCodePipelineを使って、ソースコードがGitHubの特定のブランチにプッシュされたことを契機に
サンプルアプリケーションとコンテナをビルドし、ECSにインプレースデプロイする仕組みを作っていきます。

この一連の動作をするためには、CodeBuildとCodePipeline、GitHubアカウントが必要です。
まずはこれらの準備から行い動作確認をしていきます。

準備編は以下をご参照ください。
CodePipelineからFargate(ECS)にデプロイする(1/2) - 準備編
本記事に使用した各コードは以下で公開中です。
pideoh/fargate-inplace-deploy-sample

CodeBuildの作成

CodeBuildはビルドプロジェクトとソースに同梱したbuildspec.ymlで動作します。
以降はIDEとCodeBuildコンソールとで操作します。

buildspec.ymlの作成

ソースのbuild-templateディレクトリにbuildspec.ymlファイルを作成し、以下の内容を入力します。
buildspec.ymlリファレンスをもとに実装します。

version: 0.2
 
phases:
  install:
    runtime-versions:
      docker: 18
      java: corretto11
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - export VERSION=`date '+%Y%m%d%H%M%S'`
      - $(aws ecr get-login --no-include-email)
  build:
    commands:
      - echo Build started on `date`
      - echo Building the SpringBoot Application...
      - ./gradlew build
      - echo Building the Docker image...
      - docker build -t ${REGISTORY_URI}:latest -f build-template/Dockerfile .
      - docker tag ${REGISTORY_URI}:latest ${REGISTORY_URI}:${VERSION}
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker image...
      - docker push ${REGISTORY_URI}:latest
      - docker push ${REGISTORY_URI}:${VERSION}
      - echo Writing image definitions file...
      - printf '[{"name":"sample-api","imageUri":"%s"}]' ${REGISTORY_URI}:${VERSION} > imagedefinitions.json
artifacts:
  files: 
    - imagedefinitions.json
cache:
  paths:
    - '/root/.gradle/caches/**/*'
    - '/root/.gradle/wrapper/**/*'
    - '.gradle/**/*'

ここでは、この中の重要な内容のみ記載します。

installシーケンス

ビルドの実行環境を指定します。
今回はGradleを利用してJDK 11のSpring Bootプロジェクトをビルドし、
ビルドしたアプリケーションをDockerイメージとするため、Docker 18及びCorretto11を指定します。
なお、Corretto11はランタイムをAmazon Linux 2としている場合に利用可能です。
※詳細はリファレンスを参照

post_buildシーケンス

post_buildシーケンスの最後でprintf '[{"name":"sample-api","imageUri":"%s"}]' ${REGISTORY_URI}:${VERSION} > imagedefinitions.jsonというコマンドを実行し、imagedefinitions.jsonというjsonを作成しています。
"name"のValueはECSのタスク定義のサンプルアプリケーションのコンテナ名と合わせる必要があります。
これは、CodePipelineからビルドされたコンテナをECSにデプロイする際に、コンテナイメージを橋渡しする役割をするファイルです。
規定のjsonファイルで出力し、後述のartifactsシーケンスでBuild Artifactとして後続のデプロイシーケンスに渡します。
imagedefinitions.jsonの仕様やチュートリアルについては、以下をご参照ください。
イメージ定義ファイルのリファレンス
チュートリアル: CodePipeline を使用した継続的なデプロイ

artifactsシーケンス

ここではpost_buildシーケンスで作成したimagedefinitions.jsonを、
後続のステージにBuild Artifactとして渡す定義をしています。
ビルドの結果として得られたパラメータやファイルを次のシーケンスに渡した場合は、
対象のファイルをfilesにリスト形式として渡します。

ビルドプロジェクトの作成

CodeBuildコンソールを開き、「ビルドプロジェクトを作成する」を押下し、
画面に以下の通り入力していきます。
特に、環境 - 特権付与は忘れずにチェックボックスをつけてください。
CodeBuildは今回の環境ではコンテナ上で動くため、コンテナ上からコンテナビルドをするためにはこのチェックボックスを忘れずにつける必要があります。
入力完了後、作成を押下します。

項目 入力内容
プロジェクトの設定 - プロジェクト名 任意のプロジェクト名を入力
送信元 - ソースプロバイダ GitHub
送信元 - リポジトリの URL 準備編で用意したリポジトリのURL
送信元 - 接続のステータス 「GitHubに接続」を押下し、OAuthを使用して接続
送信元 - ソースバージョン ビルドするブランチを選択
環境 - オペレーティングシステム Amazon Linux 2
環境 - ランタイム Standard
環境 - イメージ aws/codebuild/amazonlinux2-x86_64-standard:2.0
環境 - 特権付与 チェックボックスをオンにする
環境 - サービスロール 新しいサービスロール
環境 - ロール名 任意のロール名を入力
環境 - タイムアウト 10分
環境変数 名前:REGISTORY_URI、値:準備編で作成したECRのURI
Buildspec - Buildspec名 - オプショナル build-template/buildspec.yml
ログ - CloudWatch Logs - グループ名 任意のグループ名を入力
ログ - CloudWatch Logs - ストリーム名 任意のストリーム名を入力

入力し終わるとこんな感じです。
image.png
image.png

サービスロールの変更

ビルドプロジェクトを作成する際に一緒に作成したサービスロールはECRの権限を持たないため、
ビルドに失敗します。そのため、IAMコンソールから作成したIAMロールを選択し、以下のインラインポリシーをアタッチします。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "ecr:BatchCheckLayerAvailability",
                "ecr:CompleteLayerUpload",
                "ecr:GetAuthorizationToken",
                "ecr:InitiateLayerUpload",
                "ecr:PutImage",
                "ecr:UploadLayerPart"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}

CodePipelineの作成

ここからはいよいよCodePipelineを作っていきます。
CodePipelineコンソールから「っパイプラインを作成する」を押下します。

Step 1 of 5 パイプラインの設定を選択する

「パイプライン名」と「ロール名」を入力します。
image.png

Step 2 of 5 ソースステージを追加する

ソースプロバイダーにGitHubを選択し、CodeBuild同様に「GitHubに接続する」を押下し接続します。
リポジトリ・ブランチもCodeDeploy同様に設定していきます。
ここで設定したリポジトリ・ブランチにコードがプッシュされると、それを起因にCodePipelineが動作します。

image.png

Step 3 of 5 ビルドステージを追加する

プロバイダーにCodeBuildを選択し、先程作成したビルドプロジェクトを選択します。
image.png

Step 4 of 5 デプロイステージを追加する

デプロイプロバイダーにECSを選択し、作成したクラスタ名・サービス名を入力します。

image.png

Step 5 of 5 レビュー

問題ないか確認し、パイプラインを作成します。

動作確認

以上で実装は完了です。
早速動作確認をしてみましょう。

まずはCodePipelineから手動でビルドとデプロイを行います。
作成したパイプラインに入り、「変更をリリースする」を押下することでパイプラインが開始します。
完了すると以下の通り、すべて成功するはずです。
デプロイタスクはALBのdrainingがデフォルト値の300秒のため、時間がかかります。
気になる方は必要に応じて小さな値に変更してください。
image.png

ECSを確認すると、新しいリビジョンのタスク定義が作成され、タスクにデプロイされていることが確認できたと思います!

次は、リポジトリにプッシュされたことを契機にパイプラインが動作することを確認します。
任意のファイルをリポジトリに作成し、プッシュしてみます。
そうするとGitHubからCodePipelineにWebHookが走り、パイプラインが動作しました!

まとめ

準備編からECS環境をセットアップし、ECS Fargate環境にCodePipelineを使い、GitHubへのプッシュ契機でインプレースデプロイすることに成功しました。
WebHook対象のブランチをリリース環境用のブランチとすることで、マージされた瞬間にビルドとデプロイが走る、といったことがAWSサービスだけで実現できますね。

0
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?