Solved: Publishing to created SNS topic


#1

My pair of lambda functions cannot communicate via SNS. One publishes events and the other consumes them.

The first function subscribes to a topic. And I know it works because I can trigger it manually by adding to the topic. The other method is having an issue. It times out while waiting for the publish call to return.

What do I do to allow the publishing function publish to the SNS topic?

My current config looks like this

service: something

provider:
  name: aws
  runtime: nodejs4.3
  region: us-east-1
  memorySize: 128
  cfLogs: true
  iamRoleStatements:
    - Effect: 'Allow'
      Action:
        - "sns:Publish"
      Resource:
        - ${self:custom.myTopic}

custom:
  myTopic:
    Fn::Join:
      - ":"
      - - arn
        - aws
        - sns
        - Ref: AWS::Region
        - Ref: AWS::AccountId
        - myTopic

functions:
  published:
    handler: published.handler
    description: Receives SNS published events
    timeout: 90
    events:
      - sns:
          topicName: myTopic
          displayName: My topic

  publisher:
    handler: publisher.handler
    description: Publishes SNS events
    timeout: 30
    events:
      - schedule: cron(0 1 * * ? *)

I thought permissions was the issue so I added AdministratorAccess and AmazonSNSFullAccess to the created role. And that didn’t help.

My publish method is the following. I know it’s working because the topic handler lambda can publish messages back to the same topic and get the lambda launched to handle them with success.


#2

I also manually added code to the publish consuming function to post back to the same topic to verify the publishing code worked. It did, and a new sns message was posted.


#3

Manually publishing messages to the topic via the AWS console works as expected. The published method fires and works without errors.

I also added in code to post from the published lambda back to the same topic, thus causing a 2nd run of the lambda handler. Published ran twice as expected. Meaning the same code used to publish from the publisher function works. At least it works in the context of the published function while handing a message.

I’m guessing its permissions since the published lambda can publish new messages. I thought it was just the “sns:Publish” permission, but it seems there needs to be something else.


#4

It’s always hard to debug code from fragments. Have you tried adding a

.then(result => console.log("Success", result))
.catch(err => console.error("Error", err));

after the promise() to see what’s actually returned?

If you haven’t given the Lambda permissions to publish to the topic then my money is on that.


#5

Its the VPC!!

I did my best to narrow down the problem by isolating components and have discovered its the VPC settings. Now I’m trying to figure how to both publish to SNS and also connect to my RDS hosted DB. From my readings I think need a NAT gateway on a subnet that the lambda is on in addition to the subnet that the DB is on.


#6

Found this great blog post

New – Access Resources in a VPC from Your Lambda Functions


It says this

Internet Access – As soon as you enable this functionality for a particular function, the function no longer has access to the Internet by default. If your function requires this type of access, you will need to set up a Managed NAT Gateway in your VPC (see New – Managed NAT (Network Address Translation) Gateway for AWS for more information) or run your own NAT (see NAT Instances).


#7

I ran into the same thing with a function that when it was VPC enabled suddenly couldn’t interact with SQS. Solved by splitting the functions out (rather than fight with network security bods who controlled the security group config)