インフラ

ecr-deploymentを使ってCDKでECRの名前を指定してdocker pushする

ECR

こんにちは、ちゃりおです。

CDKで作成したECRに対して、Dockerイメージをpushすることがよくあります。
CDKでECRを作成して、その後ターミナルで「docker build」と「docker push」を行ってイメージをECRにpushしていました。

ターミナルでコマンド実行するのも面倒なので、CDKでそのへんもやってくれたら便利なのにと思ってやり方を調べてみました。
結論「cdklabs/cdk-ecr-deployment」を使えばできます。

Contents

CDKでECRにDockerイメージをpushする

ディレクトリ構成は以下です。

├── app
│   └── sample-app
│       └── Dockerfile
├── bin
│   └── cdk_ecr_push.ts
├── cdk.json
├── jest.config.js
└── lib
   └── cdk_ecr_push-stack.ts

CDKでsample-app-repoという名前でECRを作成して、DockerイメージをPushします。

@aws-cdk/aws-ecr-assetsではECRを指定することができない

単純にDockerイメージをECRにPushするだけなら、「aws-ecr-assets」を使うことで実現できます。

import * as cdk from '@aws-cdk/core';
import * as ecr from "@aws-cdk/aws-ecr"
import { DockerImageAsset } from "@aws-cdk/aws-ecr-assets"
import * as path  from "path"

export class CdkEcrPushStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const repo = new ecr.Repository(this, "repo", {
      repositoryName: "sample-app-repo",
      removalPolicy: cdk.RemovalPolicy.DESTROY
    })
    const image = new DockerImageAsset(this, "MyBuildImage", {
      directory: path.join("app", "sample-app")
    })
  }
}

しかし、この方法では(cdk v1.129時点)ではECRのリポジトリを指定してPushすることはできません。
「aws-cdk/assets」という名前のECRにPushされます。

cdklabs/cdk-ecr-deploymentを使ってみる

cdk-ecr-deploymentを使うことで、指定したECRにイメージを保存できます。

公式ドキュメントREADMEを参考に使ってみます。

cdk-ecr-deploymentを使うとECR間でイメージをコピーするCustomResourceが作成されます。
以下では、「aws-cdk/assets」をコピー元、ECRのレポジトリをコピー先にすることで、指定したECRへのDockerイメージを保存しています。

import * as cdk from '@aws-cdk/core';
import * as ecr from "@aws-cdk/aws-ecr"
import * as ecrdeploy from 'cdk-ecr-deployment';
import { DockerImageAsset } from "@aws-cdk/aws-ecr-assets"
import * as path  from "path"

export class CdkEcrPushStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here
    const repo = new ecr.Repository(this, "repo", {
      repositoryName: "sample-app-repo",
      removalPolicy: cdk.RemovalPolicy.DESTROY
    })
    const image = new DockerImageAsset(this, "MyBuildImage", {
      directory: path.join("app", "sample-app")
    })
    new ecrdeploy.ECRDeployment(this, 'DeployDockerImage', {
      src: new ecrdeploy.DockerImageName(image.imageUri),
      dest: new ecrdeploy.DockerImageName(`${cdk.Aws.ACCOUNT_ID}.dkr.ecr.${cdk.Aws.REGION}.amazonaws.com/${repo.repositoryName}`),
    })
  }
}

作成したECR(sample-app-repo)にイメージを保存することができました。

まとめ

CDKを使ったECRへのDockerイメージPushについてでした。
cdk-ecr-deploymenを使うことで簡単に実現できました。

本家CDKへの統合のIssueも上がっていました。
統合されたら更に便利になるので、Issueにいいね押しておきましょう!

Amzonで「AWS」の本を見てみる

楽天で「AWS」の本をみてみる!!

ECR
CDKで作成したECRをスタック削除時に同時に削除されるようにするこんにちは、ちゃりおです。 デフォルトではCDKでECRを作成して、「cdk destroy」で削除したときにECRのリポジトリが残り...
GithubActionsでECSデプロイ コンテナビルドを並行処理するこんにちは、ちゃりおです。 ECSデプロイにGithubActionsを使用しています。 コンテナビルドに時間がかかるコンテナが複数あ...
cdk
AWS CDKのADVANCED WORKSHOPやってみたこんにちは、ちゃりおです。 CDK Pipelineをざっくり試したいと思っていて、なにかいいチュートリアルないかと探していたら。「A...