It feels like a chicken and egg problem.
I’m trying to build a Docker image, add it to my ECR repository, and use it in a Lambda function using CDK V2.
Here is my code:
const repository = new ecr.Repository(this, `WorkerHelloRepository`, {
repositoryName: `worker-hello`,
imageTagMutability: ecr.TagMutability.IMMUTABLE,
imageScanOnPush: true,
removalPolicy: cdk.RemovalPolicy.DESTROY,
lifecycleRules: [
{
description: 'Keeps a maximum number of images to minimize storage',
maxImageCount: 10,
},
],
});
const asset = new DockerImageAsset(this, `WorkerHelloDockerImageAsset`, {
directory: path.join(__dirname, `../../../workers/hello`),
buildArgs: {},
});
const destinationImageName = `${repository.repositoryUri}:${asset.assetHash}`;
new ecrdeploy.ECRDeployment(this, 'EcrDeployment', {
src: new ecrdeploy.DockerImageName(asset.imageUri),
dest: new ecrdeploy.DockerImageName(destinationImageName),
});
const lambdaFunction = new lambda.DockerImageFunction(this, `WorkerHelloFunction`, {
code: lambda.DockerImageCode.fromEcr(repository, {
tagOrDigest: asset.assetHash,
cmd: ['index.newEntry'],
}),
});
repository.grantPull(lambdaFunction);
lambdaFunction.addToRolePolicy(
new cdk.aws_iam.PolicyStatement({
actions: ['ecr:BatchGetImage', 'ecr:GetDownloadUrlForLayer'],
resources: [repository.repositoryArn],
effect: cdk.aws_iam.Effect.ALLOW,
}),
);
The error returned by CloudFormation says that the image does not exist:
4:05:35 AM | CREATE_FAILED | AWS::Lambda::Function | workers-stack/work...orkerHelloFunction
Resource handler returned message: "Source image ***********.dkr.ecr.us-west-2.amazonaws.com/worker-hello:55106229314a459e2cf7fbfa14c2c03b728ffd20a70dad
3cf25ff51d7664abce does not exist. Provide a valid source image. (Service: Lambda, Status Code: 400, Request ID: 6ef7e839-ddb3-43c1-9170-c50865f6af70)" (Reques
tToken: be9bf05b-47e6-5239-da32-46cbe422853d, HandlerErrorCode: InvalidRequest)
But when I check in the ECR repository (that CloudFormation fails to delete since it’s not empty), I can see the image and its uri is correct.
I tried manually adding a dependency from the Lambda function to the created assets by doing:
lambdaFunction.node.addDependency(asset);
I’m pretty sure CDK is smart enough to actually detect this dependency anyway, and it didn’t solve the problem.
I really want to avoid having a separate stack just for ECR, but I guess that would solve the problem. What I didn’t try is to move the ECR stuff and Lambda resources in two different nested stacks and add a dependency from one to the other, but I don’t see why it would work better.
Any idea? Or even any guidance on how to solve this chicken and egg problem?