AWS SQS - CDK - how to create topic filter

Viewed 853

I'm able to create an SQS queue + lambda function and connect them via trigger/subscription.

How can I create a topic filter via CDK?

I'm able to create the topic, lambda, and trigger / subscription like so:

const queue = new sqs.Queue(this, 'OurSqsQueue', {
  queueName: 'OurSQSQueue',
});
const lambdaFunction = new lambda.Function(this,'test', {
       code: lambda.Code.fromAsset('src'),
       handler: index.lambdaHandler,
       functionName: 'test',
       runtime: lambda.Runtime.NODEJS_14_X,
     });

const eventSource = new lambdaEventSources.SqsEventSource(queue);
lambdaFunction.addEventSource(eventSource);

According to the docs Amazon SQS topic subscriber receives every message published to the topic. To receive a subset of the messages, a subscriber must assign a filter policy to the topic subscription.

enter image description here

2 Answers

Lambda event filtering for SQS, DynamoDB, and Kinesis event sources was announced last month, but is not yet supported in the CDK. There is an open feature request on github.

In the meantime, we can use the escape hatch to set filters on the underlying CfnEventSourceMapping Construct.

Here's a minimal working example:

export class LambdaEventFilterEscape extends cdk.Stack {
  constructor(scope: Construct, id: string, props: cdk.StackProps) {
    super(scope, id, props);

    const func = new lambda.Function(this, 'MyFunction', {
      code: new lambda.InlineCode('exports.handler = async (event) => console.log(event)'),
      runtime: lambda.Runtime.NODEJS_14_X,
      handler: 'index.handler',
    });

    const queue = new sqs.Queue(this, 'MyQueue');
    queue.grantConsumeMessages(func);

    const source = new lambda.EventSourceMapping(this, 'EventSourceMapping', {
      target: func,
      eventSourceArn: queue.queueArn,
    });

    // escape hatch
    const cfnSouce = source.node.defaultChild as lambda.CfnEventSourceMapping;

    cfnSouce.addPropertyOverride('FilterCriteria', {
      // https://docs.aws.amazon.com/lambda/latest/dg/invocation-eventfiltering.html#filtering-syntax
      Filters: [{ Pattern: `{\"body\": { \"Data\" : { \"Name\": [\"Zaphod\", \"Ford\" ] }}}` }],
    });
  }
}

AWS SQS and SNS are different servies. SQS has queues, SNS has topics.

I'm assuming you're indeed talking about SQS. Filtering for SQS queues was impossible until two weeks ago, when this was added.

The support for this feature has not been implemented in CDK yet.

I am not completely sure whether CloudFormation supports this at all at this point, but you can try working with the low-level CfnEventSourceMapping resource, here are the CloudFormation docs for it.

Related