Это похоже на проблему курицы и яйца. Я пытаюсь создать образ Docker, добавить его в свой репозиторий ECR и использовать в функции Lambda с помощью CDK V2.
Вот мой код:
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,
}),
);
Ошибка, возвращаемая CloudFormation, говорит о том, что изображение не существует:
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)
Но когда я проверяю репозиторий ECR (который CloudFormation не может удалить, поскольку он не пуст), я вижу изображение и его URI верны.
Я попытался вручную добавить зависимость от функции Lambda к созданным активам, выполнив:
lambdaFunction.node.addDependency(asset);
Я почти уверен, что CDK достаточно умен, чтобы в любом случае обнаружить эту зависимость, и это не решило проблему.
Я действительно хочу избежать создания отдельного стека только для ECR, но думаю, это решит проблему. Чего я не пробовал, так это перемещать элементы ECR и ресурсы Lambda в два разных вложенных стека и добавлять зависимость от одного к другому, но я не понимаю, почему это будет работать лучше.
Есть идеи? Или хотя бы какие-нибудь рекомендации о том, как решить проблему курицы и яйца?
Ваша зависимость должна быть от развертывания ECR, а не от исходного актива (поскольку лямбда-выражение не использует актив напрямую).
Вы прошли большую часть пути, это должно сработать:
const deployment = 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'],
}),
});
// Dependency on the deployment, not the asset
lambdaFunction.node.addDependency(deployment);