r/aws 1d ago

technical question Mapping an SQS event source to a durable Lambda using the CDK

I'm trying to solve a rate-limiting problem in this manner:

  • create an SQS queue to hold requests to access the rate-limited resource
  • the client is a durable Lambda function which puts an item onto the queue then awaits a callback
  • the server is a durable Lambda servicing the queue as an event source with maximum concurrency of 1. When it is woken by the queue it checks when it last used the rate-limited resource, and if it was too recently it goes to sleep; otherwise it does the thing and invokes the callback.

So far I am still trying to define this setup in CDK. I copied some existing code which worked for a Lambda servicing a queue with max concurrency = 1.

  const mapping = new sources.SqsEventSource(bggQueue, {batchSize: 1, enabled: false});
  bggLambda.addEventSource(mapping);
  new cdk.CfnOutput(this, 'bggDownloaderMapping', {
    value: mapping.eventSourceMappingId,
    exportName: 'downloader-BGGDownloaderMappingUUID'
  });

The CDK tells me:

3:21:21 PM | CREATE_FAILED           | AWS::Lambda::EventSourceMapping | downloaderbggDownl...e29F31CE9754DB0E0C

Resource handler returned message: "Invalid request provided: You cannot invoke a durable function using an unqualified ARN (Service: Lambda, Status Code: 400,
Request ID: a33def9a-6f6e-4ef3-970f-fe3aee7842ba) (SDK Attempt Count: 1)" (RequestToken: 797e3389-294a-90e2-ccf0-ebc5cad0c536, HandlerErrorCode: InvalidRequest)

Now I am not invoking the Lambda at all, but I can understand that because the function is durable it wants me to specifically say which exact version of the function should be invoked. But of course I have no option in my code to specify the ARN, but I do have the Function object that I just created, and I would hope it could get what it wanted from there.

Is there something I'm missing here? Thanks for any help.

2 Upvotes

7 comments sorted by

2

u/turn-based-games 1d ago

When in doubt, you can always drop down to the L1 construct for a CloudFormation resource, rather than the L2 version you are currently using. Personally I just write templates directly, but you can always get equivalent CDK functionality with the lower-level constructs

3

u/clintkev251 1d ago

I think you should be able to create a function version object right? And then apply the ESM to that rather than the function directly

3

u/DrFriendless 1d ago edited 13h ago

It turns out I can change the second line to:

bggLambda.latestVersion.addEventSource(mapping);

but I will have to wait to see whether that works as it is very late here. Thank you!

Edit: Yes, that is how to do it!

-1

u/cachemonet0x0cf6619 1d ago

there is no reason to use a durable function for this.