cdkでECRのイメージがpushされずlambda関数がそれを読み込めないエラー

# Envs

```
  "dependencies": {
    "@aws-cdk/aws-lambda": "^1.204.0",
    "@aws-cdk/aws-s3": "^1.204.0",
    "@aws-cdk/aws-s3-deployment": "^1.204.0",
    "@aws-cdk/core": "^1.204.0",
    "aws-cdk-lib": "2.126.0",
    "cdk-ecr-deployment": "^3.0.68",
    "constructs": "^10.0.0",
    "source-map-support": "^0.5.21"
  },
```

# 問題点
awsのcdkを使用し、別stackで定義したECRリポジトリにイメージをプッシュ、そしてlambda関数を作成するコードが動かなかった。

```ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as ecr from 'aws-cdk-lib/aws-ecr';
import * as ecr_assets from 'aws-cdk-lib/aws-ecr-assets';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';
import { ECRDeployment, DockerImageName } from 'cdk-ecr-deployment';

interface LambdaDefineThemeStackProps extends cdk.StackProps {
  bucket: s3.Bucket;
  xxxLambdaArn: string;
}

export class LambdaDefineThemeStack extends cdk.Stack {
  constructor(
    scope: Construct,
    id: string,
    props: LambdaDefineThemeStackProps
  ) {
    super(scope, id, props);

    const bucket = props.bucket;
    const xxxLambdaArn = props.xxxLambdaArn;

    const repository = ecr.Repository.fromRepositoryName(
      this,
      'GetEcrRepository',
      'lambda-repository-define-theme'
    );

    const dockerAsset = new ecr_assets.DockerImageAsset(
      this,
      'LambdaDockerImageDefineTheme',
      {
        directory: 'runtime/define_theme',
      }
    );

    const awsAccount = 'xxxxxxxxxx';
    const tag = 'latest';
    new ECRDeployment(
      this,
      'DeployDockerImageDefineTheme',
      {
        src: new DockerImageName(dockerAsset.imageUri),
        dest: new DockerImageName(
          `${awsAccount}.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-repository-define-theme:${tag}`
        ),
      }
    );

    const lambdaDefineTheme = new lambda.DockerImageFunction(
      this,
      'LambdaFunctionDefineTheme',
      {
        code: lambda.DockerImageCode.fromEcr(repository, {
          tag: tag,
        }),
        architecture: lambda.Architecture.X86_64,
        timeout: cdk.Duration.seconds(30),
        environment: {
          BUCKET_NAME: bucket.bucketName,
          XXX_LAMBDA_ARN: xxxLambdaArn,
        },
      }
    );

    bucket.grantRead(lambdaDefineTheme);

    const lambdaInvokePolicy = new iam.PolicyStatement({
      effect: iam.Effect.ALLOW,
      actions: ['lambda:InvokeFunction'],
      resources: [xxxLambdaArn],
    });
    lambdaDefineTheme.addToRolePolicy(lambdaInvokePolicy);
  }
}
```

```terminal
14:58:49 | CREATE_FAILED        | AWS::Lambda::Function       | LambdaFunctionDefineTheme0C0ABCFC
Resource handler returned message: "Source image xxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-repository-define-theme:latest does not exist. Provide a valid source image. (Service: Lambda, St
atus Code: 400, Request ID: 870882f9-78ad-4544-a14b-f04f27599c5f)" (RequestToken: 4b5b394e-858c-724d-7273-75febbaacff5, HandlerErrorCode: InvalidRequest)
```

# 解決法

原因はイメージがプッシュされる前にLambda関数を作成しようと試みたため、イメージが存在せず、エラーになった。
そのため、イメージプッシュ後にLambda関数が作成されるように依存関係を設定する必要がある。
次のページが参考になった。

https://stackoverflow.com/questions/77902359/cdk-ecrdeployment-source-image-does-not-exist-provide-a-valid-source-image

次の一文を追加するだけである。

```ts
lambdaDefineTheme.node.addDependency(ecrDeployment);
```

コードは次のようになる。

```ts
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
import * as ecr from 'aws-cdk-lib/aws-ecr';
import * as ecr_assets from 'aws-cdk-lib/aws-ecr-assets';
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';
import { ECRDeployment, DockerImageName } from 'cdk-ecr-deployment';

interface LambdaDefineThemeStackProps extends cdk.StackProps {
  bucket: s3.Bucket;
  xxxLambdaArn: string;
}

export class LambdaDefineThemeStack extends cdk.Stack {
  constructor(
    scope: Construct,
    id: string,
    props: LambdaDefineThemeStackProps
  ) {
    super(scope, id, props);

    const bucket = props.bucket;
    const xxxLambdaArn = props.xxxLambdaArn;

    const repository = ecr.Repository.fromRepositoryName(
      this,
      'GetEcrRepository',
      'lambda-repository-define-theme'
    );

    const dockerAsset = new ecr_assets.DockerImageAsset(
      this,
      'LambdaDockerImageDefineTheme',
      {
        directory: 'runtime/define_theme',
      }
    );

    const awsAccount = 'xxxxxxxxxx';
    const tag = 'latest';
    // 返り値を定数に入れる
    const ecrDeployment = new ECRDeployment(
      this,
      'DeployDockerImageDefineTheme',
      {
        src: new DockerImageName(dockerAsset.imageUri),
        dest: new DockerImageName(
          `${awsAccount}.dkr.ecr.ap-northeast-1.amazonaws.com/lambda-repository-define-theme:${tag}`
        ),
      }
    );

    const lambdaDefineTheme = new lambda.DockerImageFunction(
      this,
      'LambdaFunctionDefineTheme',
      {
        code: lambda.DockerImageCode.fromEcr(repository, {
          tag: tag,
        }),
        architecture: lambda.Architecture.X86_64,
        timeout: cdk.Duration.seconds(30),
        environment: {
          BUCKET_NAME: bucket.bucketName,
          XXX_LAMBDA_ARN: xxxLambdaArn,
        },
      }
    );

    lambdaDefineTheme.node.addDependency(ecrDeployment); // 追加

    bucket.grantRead(lambdaDefineTheme);

    const lambdaInvokePolicy = new iam.PolicyStatement({
      effect: iam.Effect.ALLOW,
      actions: ['lambda:InvokeFunction'],
      resources: [xxxLambdaArn],
    });
    lambdaDefineTheme.addToRolePolicy(lambdaInvokePolicy);
  }
}
```