Amazon Web Services ブログ

Amazon ECR をソースとしてコンテナイメージの継続的デリバリパイプラインを構築する

2018 年 11 月 27 日(米国時間)、Amazon Elastic Container Registry (Amazon ECR) を AWS CodePipline のソースプロバイダとして利用可能になりました。これにより Amazon ECR に新しいイメージをアップロードすることにより、AWS CodePipelineを起動することができるようになります。AWS Developer Tools による CI/CD 実現が一段と容易になりました。

Amazon ECR をソースとして使うには、AWS CodePipline コンソールでAWS CodeDeploy による Blue/Green デプロイメントを実装している必要があります。CodePipelineを使わず、Amazon Elastic Container Service (Amazon ECS) コンソールを使って Blue/Green デプロイメントを実装するより詳しい情報については、AWS CodeDeploy による AWS Fargate と Amazon ECS でのBlue/Greenデプロイメントの実装を参照してください。

この投稿では Amazon ECR とAWS CodePipeline を使用してエンドツーエンドの継続的デリバリ (CD) パイプラインを構築する方法について解説します。ここではアップストリームのベースイメージが更新されたらコンテナイメージを更新ためのパイプラインを作る一連の流れを説明します。

事前準備

作業にかかる前に以下のリソースが用意されていることを確認してください。

  • ベースイメージの Dockerfile が配置されているソースコードリポジトリと、イメージを配置するための Docker イメージリポジトリ。この手順では以下のようなシンプルなベースイメージのDockerfileを使用します。

FROM alpine:3.8
RUN apk update
RUN apk add nodejs
  • あなたのアプリケーションの Dockerfile とソースコードが置かれたソースコードリポジトリと、あなたのイメージを配置するための Docker イメージリポジトリ。アプリケーションの Dockerfile として、ベースイメージを使用し、以下のアプリケーションコードを追加します。ベースイメージのリポジトリURI ( 012345678910.dkr.ecr.us-east-1.amazonaws.com/base-image) はあなたが使用するものに修正してください。また、 app.js というファイルをDockerfileと同じディレクトリに配置してください。中身は空でもかまいません。

FROM 012345678910.dkr.ecr.us-east-1.amazonaws.com/base-image
ENV PORT=80
EXPOSE $PORT
COPY app.js /app/
CMD ["node", "/app/app.js"]

このウォークスルーでは AWS CodeCommit をソースコードリポジトリとして、Amazon ECR を Docker イメージリポジトリとして使用します。詳しくは AWS CodeCommit ユーザーガイドにある Create an AWS CodeCommit Repository と、Amazon Elastic Container Registry ユーザーガイドにある Creating a Repository を参照してください。

注記: ソースコードリポジトリとイメージリポジトリは同じリージョンに作成してください

IAM サービスロールを作成する

このウォークスルーでは、Docker イメージをビルドし、Amazon ECR へプッシュするために AWS CodeBuild と AWS CodePipeline を使用します。いずれのサービスも Identity and Access Management (IAM) サービスロールを使用してAmaon ECR を API で操作します。サービスロールは Amazon ECR を呼び出すために必要な認可ポリシーを持っている必要があります。以下の手順で CodeBuild サービスロールに必要な権限を付与します。

CodeBuild サービスロールを作るには

  1. IAM コンソールで こちらの手順に従い、CodeBuild サービスロールを作成する
  2. ステップ 10 では、ロールに AmazonEC2ContainerRegistryPowerUser ポリシーも追加する

ベースイメージに対するビルド仕様ファイルを作成する

ビルド仕様ファイル (build spec ファイル)は AWS CodeBuild がビルドを実行するために必要なビルドコマンド群と関連する設定が記載されており、YAMLで記述します。CodeBuildにベースイメージをビルドする方法を示すため、buildspec.yml ファイルをソースコードリポジトリに追加します。ここで示すビルド仕様の例は以下のような内容です。

  • Pre-build ステージ
    • Amazon ECR へサインイン
    • リポジトリ URI をあなたのECR イメージにセットし、イメージタグとしてソースの Git コミット ID の先頭7文字を追加
  • Build ステージ
    • Dockerイメージをビルドし、最新の Git コミット ID でタグ付け
  • Post-build ステージ
    • 両方のタグに対して Amazon ECR リポジトリにイメージをプッシュ
version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
      - REPOSITORY_URI=012345678910.dkr.ecr.us-east-1.amazonaws.com/base-image
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG

buildspec.yml をあなたのソースコードリポジトリに追加するには

  1. テキストエディタで新規ファイルを開き上記のコードをコピー&ペースト
  2. REPOSITORY_URL の値 ( 012345678910.dkr.ecr.us-east-1.amazonaws.com/base-image ) をあなたの Dockerイメージの Amazon ECR リポジトリ URI (イメージタグを除く) で置き換えます。base-image をあなたの ベース Docker イメージ名で置き換えます
  3. ファイルを buildspec.yml という名前で保存し、ソースコードリポジトリへコミットしプッシュ
git add .
git commit -m "Adding build specification."
git push

あなたのアプリケーション用のビルド仕様ファイルを作成する

CodeBuildにあなたのソースコードとアプリケーションイメージをビルドする方法を伝えるため、buildspec.yamlファイルをソースコードリポジトリに追加します。ここで示すビルド仕様は次のような内容です。

  • Pre-build ステージ
    • Amazon ECR へサインイン
    • リポジトリ URI をあなたのECR イメージにセットし、イメージタグとしてソースの Git コミット ID の先頭7文字を追加
  • Build ステージ
    • Dockerイメージをビルドし、最新の Git コミット ID でタグ付け
  • Post-build ステージ
    • 両方のタグに対して Amazon ECR リポジトリにイメージをプッシュ
version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
      - REPOSITORY_URI=012345678910.dkr.ecr.us-east-1.amazonaws.com/hello-world
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=build-$(echo $CODEBUILD_BUILD_ID | awk -F":" '{print $2}')
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG
      - printf '[{"name":"hello-world","imageUri":"%s"}]' $REPOSITORY_URI:$IMAGE_TAG > imageDetail.json
  artifacts:
    files:
      - imageDetail.json

buildspec.yml をあなたのソースコードリポジトリに追加するには

  1. テキストエディタで新規ファイルを開き上記のコードをコピー&ペースト
  2. REPOSITORY_URL の値 ( 012345678910.dkr.ecr.us-east-1.amazonaws.com/hello-world ) をあなたの Dockerイメージの Amazon ECR リポジトリ URI (イメージタグを除く) で置き換えます。hello-world をあなたのサービスのタスク定義で参照しているDockerイメージのコンテナ名で置き換えます
  3. ファイルを buildspec.yml という名前で保存し、ソースコードリポジトリへコミットしプッシュ
git add .
git commit -m "Adding build specification."
git push

ベースイメージの継続的デプロイパイプラインを作成する

AWS CodePipelineのウィザードを使用してパイプラインのステージを作成します。(この手順はDeveloper Tools の新しい画面に基づいて記載しています)

  1. AWS CodePipelineのコンソール https://console.aws.amazon.com/codepipeline/ を開きます。
  2. Welcome ページで、[パイプラインの作成] をクリックします。これが最初の利用の場合、Welcomeページの代わりに紹介ページが表示されます。その場合は Get Started Now をクリックしてください。
  3. <Step 1: パイプラインの設定の選択> ページで、パイプライン名を入力し、他はそのままにして [次へ] をクリックします。ここでは [base-image] とします。
  4. <Step 2: ソースステージの追加> ページで、ソースプロバイダとして AWS CodeCommit を選択します。
    1. <リポジトリ名> としてソースコードの配置場所として使うリポジトリの名前を選択します。
    2. <ブランチ名> として使用するブランチ名を指定し、[次へ] をクリックします。
  5. <Step 3: ビルドステージの追加> ページで、ビルドプロバイダとして AWS CodeBuildを選択し、[Create project] をクリックします。
    1. <プロジェクト名> にこのウォークスルー用のプロジェクト名を入力します。ここでは [base-image] とします。
    2. <オペレーティングシステム> で [Ubuntu] を選択します。
    3. <ランタイム> で [Docker] を選択します。
    4. <ランタイムバージョン> で [[aws/codebuild/docker:17.09.0]] を選択します。
    5. <サービスロール> で [既存のサービスロール] を選択し、先の手順で作成した IAM ロールを選択します。次に <AWS CodeBuild にこのサービスロールの編集を許可し、このビルドプロジェクトでの使用を可能にする> のチェックを外します。
    6. [CodePipelineに進む] をクリックします。CodePipelineの画面に戻ります。
    7. [次へ] をクリックします。
  6. <Step 4: デプロイステージの追加> ページで、[スキップ] をクリックし、確認パネルでも [スキップ] をクリックします。
  7. <Step 5: 確認> ページで、パイプラインの設定内容を確認し、[パイプラインの作成] をクリックします。

アプリケーションイメージの継続的デプロイメントパイプラインを作成する

アプリケーションイメージのパイプラインはアプリケーションソースコードへの変更と上流のベースイメージへの変更によって起動されます。まずパイプラインを作成し、次にソースステージを追加します。

  1. AWS CodePipelineのコンソール https://console.aws.amazon.com/codepipeline/ を開きます。
  2. Welcome ページで、[パイプラインの作成] をクリックします。
  3. <Step 1: パイプラインの設定の選択> ページで、パイプライン名を入力し、他はそのままにして [次へ] をクリックします。ここでは hello-world とします。
  4. <Step 2: ソースステージの追加> ページで、ソースプロバイダとして Amazon ECR を選択します。
    1. <Repository name> としてベースイメージの配置場所として使うECRリポジトリの名前を選択します。ここでは [base-image] とします。
    2. [次へ] をクリックします。
  5. <Step 3: ビルドステージの追加> ページで、ビルドプロバイダとして AWS CodeBuildを選択し、[Create project] をクリックします。
    1. <プロジェクト名> にこのウォークスルー用のプロジェクト名を入力します。ここでは [hello-world] とします。
    2. <オペレーティングシステム> で [Ubuntu] を選択します。
    3. <ランタイム> で [Docker] を選択します。
    4. <ランタイムバージョン> で AWS を選択します。
    5. <サービスロール> で [既存のサービスロール] を選択し、先の手順で作成した IAM ロールを選択します。次に <AWS CodeBuild にこのサービスロールの編集を許可し、このビルドプロジェクトでの使用を可能にする> のチェックを外します。
    6. [CodePipelineに進む] をクリックします。CodePipelineの画面に戻ります。
    7. [次へ] をクリックします。
  6. <Step 4: デプロイステージの追加> ページで、[スキップ] をクリックし、確認パネルでも [スキップ] をクリックします。
  7. <Step 5: 確認> ページで、パイプラインの設定内容を確認し、[パイプラインの作成] をクリックします。

パイプラインは失敗します。これはアプリケーションのソースコードが不足しているためです。そこでパイプラインを編集してソースステージにアクションを追加します。

  1. AWS CodePipelineのコンソール https://console.aws.amazon.com/codepipeline/ を開きます。
  2. Welcome ページで、<hello-world> パイプラインを選択します。
  3. パイプラインのページで、[編集] をクリックします。
  4. <Editing: hello-world> ページで、<編集: Source> ボックスの [ステージを編集] をクリックします。
  5. 既存のソースアクション (Amazon ECR) の編集アイコンをクリックします。
    1. 出力アーティファクトを [BaseImage] に変更して [保存] をクリックします。
  6. [アクションの追加] をクリックし、<アクション名> に名前をつけます。ここでは例として [Code] とします。
    1. <アクションプロバイダ> として [AWS CodeCommit] を選択します。
    2. <リポジトリ名> としてアプリケーションソースコードの CodeCommit リポジトリ名を選択します。
    3. <ブランチ名> としてブランチを選択します。
    4. <出力アーティファクト> として [SourceArtifact] を入力し、[保存] をクリックします。
  7. <Editing: hello-world> ページで、[保存] をクリックし、確認パネルでも [保存] をクリックします。

エンドツーエンドのパイプラインをテストします

これでエンドツーエンドの AWS ネイティブな継続的デプロイメントを実行するために必要なものを全てパイプラインに設定しました。さあ、ベースイメージリポジトリにコードの変更をプッシュし、パイプラインの動作をテストしましょう。

  1. ベースイメージのソースコードリポジトリに変更を加え、変更をコミット、プッシュします。
  2. AWS CodePipelineのコンソール https://console.aws.amazon.com/codepipeline/ を開きます。
  3. ベースイメージのパイプライン <base-image> を選択します。
  4. パイプラインの進捗を確認します。ベースイメージがビルドされ、ECRへプッシュされると、アプリケーションイメージのパイプラインもトリガされます。パイプラインの実行が完了すると、アプリケーションイメージは Amazon ECR へプッシュされ、アプリケーションをデプロイする準備が整います。継続的デプロイについてのより詳しい情報については、AWS CodePipeline ユーザーガイドの Create a Pipeline with an Amazon ECR Source and ECS-to-CodeDeploy Deployment を参照してください。

まとめ

このブログでは Amazon ECR と AWS CodePipeline を使った完全なエンドツーエンドの継続的デプロイ (CD) パイプラインを作る方法を紹介しました。新しいイメージを Amazon ECR へアップロードすることで、AWS CodePipline のパイプラインを起動できることを確認しました。AWS CodePipeline による Amazon ECR のサポートによって、AWS Developer Tools による継続的デリバリパイプラインのセットアップがより容易になりました。

原文は Build a Continuous Delivery Pipeline for Your Container Images with Amazon ECR as Source です。翻訳はSA大村が担当しました。