aws-cdk add SQS eventSource to existing Lambda
I'm creating multiple SQS queues, and I want to add a Lambda trigger after the queues are created. I'm getting an error (see below) when I do the cdk synth command.
I'm using the version 1.130 of aws-cdk and the packages are all the same version (1.130.0)
Error with build TypeError: Cannot read property 'scopes' of undefined
Looking at the stack trace error it fails at the lambdaFunction.addEventSource section.
I'm following the CDK documentation (https://docs.aws.amazon.com/cdk/api/v1/docs/aws-lambda-event-sources-readme.html) and based on that I think I'm following the right steps.
Below is the code I'm using:
const cdk = require(`@aws-cdk/core`);
const sqs = require(`@aws-cdk/aws-sqs`);
const { SqsEventSource } = require(`@aws-cdk/aws-lambda-event-sources`);
const lambda = require(`@aws-cdk/aws-lambda`);
const fs = require(`fs`);
const { env } = require(`process`);
class PVInfraSQSTopic extends cdk.Construct {
constructor(scope, id, props) {
super(scope, id, props);
const buildEnvironment = JSON.parse(fs.readFileSync(`./config/`+JSON.parse(env.CDK_CONTEXT_JSON).config+`.json`, `utf8`));
const sqsDLQ = buildEnvironment.sqsDeadLetterQueue;
const lambdas = buildEnvironment.sqsLambdaTrigger;
const sqsQueues = buildEnvironment.sqsQueues;
const alias = buildEnvironment.alias;
const region = buildEnvironment.region;
const awsAccount = buildEnvironment.awsAccount;
const queueName = `sqs-queue`;
// Create Dead Letter Queue.
const dlq = new sqs.Queue(this, `SQSBuild`, {
queueName: sqsDLQ
});
// Create queues and configure dead letter queue for said queues.
sqsQueues.map((item) => {
new sqs.Queue(this, `queue-${item}`, {
queueName: `${item}`,
deadLetterQueue: {
maxReceiveCount: 3,
queue: dlq
}
});
});
// Add SqsEventSource (Lambda Triggers) to new SQS queues
const lambdaFunction = lambda.Function.fromFunctionAttributes(this, `function`, {
functionArn: `arn:aws:lambda:${region}:${awsAccount}:function:${lambdas}:${alias}`
});
lambdaFunction.addEventSource(new SqsEventSource(queueName, {
batchSize: 10
}));
}
}
module.exports = { PVInfraSQSTopic };
The lambda already exists, so that is why I'm not creating it as part of this stack.
Your first problem is that you are passing the SqsEventSource
constructor a string
(queueName
), when it requires an IQueue
.
It still won't synth, through. You also need to give CDK more information about your existing lambda, namely the lambda's IAM role.
Here's a minimal working example. I am importing existing lambda resource ARNs that were exported as StackOutputs in the existing Lambda stack, but this is an implementation detail.
export class SqsExistingEventSourceStack extends cdk.Stack {
constructor(scope: Construct, id: string, props: cdk.StackProps) {
super(scope, id, props);
const q = new sqs.Queue(this, 'MyQueue');
const lambdaFunction = lambda.Function.fromFunctionAttributes(this, `function`, {
functionArn: cdk.Fn.importValue('MinimalLambdaArn'),
role: iam.Role.fromRoleArn(this, 'importedRole', cdk.Fn.importValue('MinimalLambdaRoleArn')),
});
lambdaFunction.addEventSource(new sources.SqsEventSource(q, {batchSize: 10,}) );
}
}
The OP does not show how you are adding the PVInfraSQSTopic
construct to a stack, which may also be a source of "scope" errors.