Search code examples
amazon-web-servicesaws-lambdaamazon-sqsserverless-framework

Serverless Framework does not create SQS queue before Lambda with queue trigger


Using Serverless Framework, how can I make my Lambda function depend on an SQS queue from the resources section as it is the trigger for the function itself?

In my serverless.yaml, I am defining a new queue and Lambda function.

Then, I want to use the queue as an event source (trigger) for my Lambda function.

I do that by creating the queue ARN manually:

functions:
  consumer:
    handler: App\Service\Consumer
    events:
      - sqs:
          arn:
            Fn::Join:
              - ':'
              - arn:aws:sqs
              - Ref: AWS::Region
              - Ref: AWS::AccountId
              - ${opt:stage}-skill-assigner

And creating the queue in resources:

resources:
  Resources:
    SkillAssignerQueue:
      Type: AWS::SQS::Queue
      Properties:
        QueueName: ${opt:stage}-skill-assigner

This works fine if I create the queue in a deployment prior to using it as a function trigger.

But if I try to deploy both of them, it fails with this error when it tries to create the event source mapping:

Invalid request provided: Error occurred while ReceiveMessage. SQS Error Code: AWS.SimpleQueueService.NonExistentQueue. SQS Error Message: The specified queue does not exist for this wsdl version.


Solution

  • Fn::Join enables string concatenation which doesn't inform the Serverless Framework (SF) about the dependency of the function on the queue.

    We visually can see that but it needs to be done declaratively.

    To make this link obvious to SF, use Fn::GetAtt: instead.

    It will inform Serverless Framework about the dependency of the Lambda function on the SQS queue.

    This should work:

    functions:
      consumer:
        handler: App\Service\Consumer
        events:
          - sqs:
              arn:
                Fn::GetAtt:
                  - SkillAssignerQueue
                  - Arn
    resources:
      Resources:
        SkillAssignerQueue:
          Type: AWS::SQS::Queue
          Properties:
            QueueName: ${opt:stage}-skill-assigner