How to add a reference to SNS ARN?

I’m trying to do something like shown below. Create a lambda which handles notifications from a sns topic, and a lambda used to published to the same topic.

How can I get the SNS ARN set to snsAlertPublisher lambda ?

  snsAlertHandler:
    handler: 'snsAlert.handler'
    events:
      - sns: SnsAlertDispatch

  snsAlertPublisher:
    handler: 'snsAlertPublisher.handler'
    environment:
      snsArn: ?????

Thanks
Jesper

Something like this should work:

provider:
  iamRoleStatements:
    - Effect: Allow
      Action:
        - SNS:Publish
      Resource: { "Fn::Join" : ["", ["arn:aws:sns:${self:custom.region}:", { "Ref" : "AWS::AccountId" }, ":${self:custom.alertDispatchTopic}" ] ]  }

custom:
  stage: ${opt:stage, self:provider.stage}
  region: ${opt:region, self:provider.region}
  alertDispatchTopic: "${self:service}-alert-dispatch-${self:custom.stage}"

functions:
  snsAlertHandler:
    handler: 'snsAlert.handler'
    events:
      - sns: ${self:custom.alertDispatchTopic}

  snsAlertPublisher:
    handler: 'snsAlertPublisher.handler'
    environment:
      snsArn: { "Fn::Join" : ["", ["arn:aws:sns:${self:custom.region}:", { "Ref" : "AWS::AccountId" }, ":${self:custom.alertDispatchTopic}" ] ]  }
7 Likes

Nice, this works. Thank you very much.

One quick question, what is the reason for this
stage: ${self:opt.stage, self:provider.stage}
instead of simply using ${self:opt.stage}

Thanks

It allows the user to override the stage on the command line.

2 Likes

I’m pretty new to serverless and this might be a dumb question, { "Fn::Join" : ["", ["arn:aws:sns:${self:custom.region}:", { "Ref" : "AWS::AccountId" }, ":${self:custom.alertDispatchTopic}" ] ] } yields an object during runtime that lacks the account ID (i.e. it just has { "Ref" : "AWS::AccountId" }). How do you get this to reduce out to a string?

I should note that I’m testing this in serverless-offline so that might affect this as well.

@johnhaley81 It’s Cloud Formation syntax that’s resolved during deployment. If you’re using serverless-offline then it probably won’t work. You could try using different environment variables for each stage (see this) then use that syntax for prod and put the ARN for an SNS topic you manually created into development.

2 Likes

Perfect. Thanks @buggy!

Is there a way to put the Arn etc into an environment block, so you don’t repeat the Fn::Join in two places ?