16

I'm building a Serverless app that defines an SQS queue in the resources as follows:

resources:
  Resources:
    TheQueue:
      Type: "AWS:SQS:Queue"
      Properties:
        QueueName: "TheQueue"

I want to send messages to this queue from within one of the functions. How can I access the URL from within the function? I want to place it here:

const params = {
    MessageBody: 'message body here',
    QueueUrl: 'WHATS_THE_URL_HERE',
    DelaySeconds: 5
};
Nick ONeill
  • 7,341
  • 10
  • 47
  • 61

3 Answers3

27

This is a great question!

I like to set the queue URL as an ENV var for my app!

So you've named the queue TheQueue.

Simply add this snippet to your serverless.yml file:

provider:
  name: aws
  runtime: <YOUR RUNTIME>
  environment:
    THE_QUEUE_URL: { Ref: TheQueue }

Serverless will automatically grab the queue URL from your CloudFormation and inject it into your ENV.

Then you can access the param as:

const params = {
    MessageBody: 'message body here',
    QueueUrl: process.env.THE_QUEUE_URL,
    DelaySeconds: 5
};
noetix
  • 4,773
  • 3
  • 26
  • 47
Aaron Stuyvenberg
  • 3,437
  • 1
  • 9
  • 21
  • 1
    Great, it helped me after I failed several times with GetAtt and Url and QueueUrl :). Why does a queue have no Url attribute? – Tien Do Apr 13 '21 at 10:36
4

You can use the Get Queue URL API, though I tend to also pass it in to my function. The QueueUrl is the Ref value for an SQS queue in CloudFormation, so you can pretty easily get to it in your CloudFormation. This handy cheat sheet is really helpful for working with CloudFormation attributes and refs.

Jason Wadsworth
  • 8,059
  • 19
  • 32
1

I go a bit of a different route. I, personally, don't like storing information in environment variables when using lambda, though I really like Aaron Stuyvenberg solution. Therefore, I store information like this is AWS SSM Parameter store.

Then in my code I just call for it when needed. Forgive my JS it has been a while since I did it. I mostly do python

var ssm = new AWS.SSM();
const myHandler = (event, context) => {
    var { Value } = await ssm.getParameter({Name: 'some.name.of.parameter'}).promise()

    const params = {
        MessageBody: 'message body here',
        QueueUrl: Value,
        DelaySeconds: 5
    };
}

There is probably some deconstruction of the returned data structure I got wrong, but this is roughly what I do. In python I wrote a library that does all of this with one line.

Buddy Lindsey
  • 3,560
  • 6
  • 30
  • 42