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.