Events between functions

I have two functions and I want the first to invoke the second through an event, like SNS. So the first function needs to publish a message to the SNS topic and for that, it needs the ARN of that topic. I figured the best way to do this was to use Lambda config variables, but I can’t figure out a simple way to get the ARN of the topic that gets created for the second function. I got it to work by referencing the logical name that serverless creates, but I can’t use a topic name that starts with the stage because of how serverless normalizes the name. It also feels like a brittle hack. I’d prefer to just create the topic in the resource section and reference it, but the SNS event doesn’t seem to handle that. Here’s an example that works. Is there a better way?

foo:
  handler: handle.foo
  environment:
    barTopic:
      Ref: SNSTopicBartopic
bar:
  handler: handle.bar
  events:
    - sns: bar-topic

If you don’t mind moving the stage to last then something like this seems to work:

custom:
  stage: "${opt:stage, self:provider.stage}"
  appInstalledTopic: "${self:service}-app-installed-${self:custom.stage}"

functions:
  authCallback:
    handler: authCallback.handler
    events:
      - http:
          path: auth/callback
          method: get
    environment:
      APP_INSTALLED_TOPIC_ARN:
        Ref: "SNSTopicShopifyappinstalled${self:custom.stage}"

I did this and it does work. I was just hoping there’s a real way to do this - one that doesn’t require knowing about serverless internals and hoping they don’t change and break your stuff.

The best way I see is define the topic in the resources and for the SNS event to handle a Ref to that resource. Is this worth a feature request?

I found a slightly better solution that relies on how AWS formats SNS ARNs rather than how Serverless formats logical Ids. This is what I’m going with until Serverless comes up with a better solution.

foo:
  handler: handle.foo
  environment:
    barTopic:
      Fn::Join:
          - ":"
          - - arn
            - aws
            - sns
            - Ref: AWS::Region
            - Ref: AWS::AccountId
            - ${opt:stage}-bar-topic
bar:
  handler: handle.bar
  events:
    - sns: ${opt:stage}-bar-topic
3 Likes

Thankyou @benschoenfeld, your solution works. I had something similar to this but something was wrong, after copying your answer I got the desired result similar to your original question.

I had also previously tried creating my own topic under resources, and then referencing it in the sns event setup. According to the documentation it should be possible to specify an arn in the event setup, and rather than creating the topic (when you specify a topicName and displayName), it references an existing topic, but I couldn’t get that to work.

I definitely think this is worth improving, did you end up creating a ticket for this?