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関数を作成するコードが動かなかった。
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);
}
}
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関数が作成されるように依存関係を設定する必要がある。
次のページが参考になった。
次の一文を追加するだけである。
lambdaDefineTheme.node.addDependency(ecrDeployment);
コードは次のようになる。
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);
}
}