CDKで既存のECRの情報をソースコードに埋め込まずにコマンド実行時にパラメータとして与えたい

はじめに

CDKを使ってECS環境を作ろうとしたときに、色々とハマったのでその内容をメモとして残しています。今回は、ECRの取得について。

ECRの取得

ECS環境を作ろうとしたときに、新規にECR環境を作ることは少なく、すでに既存のECR環境があることが多いかなと思います。このような状況では、ECRの名前からIRepositoryを返すメソッドであるfromRepositoryNameを使います。

docs.aws.amazon.com

このとき第3引数でレポジトリ名を指定しますが、直接ソースコード上に値を埋め込むのではなくコマンド実行時にパラメータとして与えたいと考えました。

パラメータの取得

CDKにはコンテキスト値というものがあり、--contextオプションを指定することで値を取得することができるようです。

docs.aws.amazon.com

実際にやってみます。TypeScriptで実装したCDKのソースコードは以下のような形になります。this.node.tryGetContextの部分でコマンド実行時にパラメータで与えられた値を読み込み、その値を持ってECRの情報を取得しています。結果確認としてCfnOutputリポジトリのURLを出力するようにしています。

import * as cdk from 'aws-cdk-lib';
import { Repository } from 'aws-cdk-lib/aws-ecr';
import { Construct } from 'constructs';

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

    const ecrName = this.node.tryGetContext("ecrName");

    const ecr = Repository.fromRepositoryName(this, "ECR", ecrName);

    new cdk.CfnOutput(this, "ECR info", {
      value: ecr.repositoryUri,
    });
  }
}

注意点は、Repository.fromRepositoryName(this, "ECR", ecrName);の第一引数です。ここをscopeにすると、以下のエラーメッセージが出て動きませんでした。

Error: Import at 'ECR' should be created in the scope of a Stack, but no Stack found

実行

実行時にも注意点が一つ。npm run cdkのようにnpm runを使うときにはオプションの渡し方に注意が必要です。

docs.npmjs.com

今回の例では、以下のように--を付与する必要があります。

$ npm run cdk synth -- --context ecrName=hogehoge

--を付与していない場合、No stacks match the name(s) ecrName=hogehogeというエラーメッセージが出て動きませんでした。

結果

以上のことを実施すると、結果としてCfnOutputで指定した値が無事出力され、fromRepositoryNameによりECRの情報が取得することができました。

考察

今回はfromRepositoryNameを使って既存のECRの情報を取得する方法について記しました。thisscopeの違いやオプションの指定の方法など色々とハマるところがあるのが今回の注意点かなと考えています。