skip to Main Content

I have a very simply Lambda function:

import boto3

def lambda_handler(event, context):
    snsTopicArn="arn:aws:sns:us-west-2:REDACTED:keiths-test-topic"
    snsClient = boto3.client('sns')
    message="This is a test"
    print("before snsClient.publish")
    response = snsClient.publish(TopicArn=snsTopicArn, Message=message, Subject="This is a test")
    print(response)
    return(response)

When I run it, it hangs at the snsClient.publish() statement until the function times out. I’ve increate the timeout to over a minute, and it doesn’t help. The Lambda function is connected to my VPC, which does have an Internet Gateway so I would think it wouldn’t have any problems getting to the appropriate AWS API endpoint. If I run the same function, without connecting it to my VPC though, it does run as expected. So, the problem does seem to have something to do with running it from my VPC.

Note that if I run the exact same code from an EC2 instance running in the same VPC, in the same subnet, it runs just fine.

Of course, this is just a code segment of a larger piece of code, and that code also reads from an S3 bucket, but for some reason it hangs if it tries to read an object that doesn’t exist. I don’t know if the two hangs are related or not.

I created an SNS VPC endpoint that is attached to my VPC and subnet. The SG associated with it has an inbound rule to allow all traffic from the VPC’s CIDR and has an unrestricted outbound rule.

I’ve tried increasing the Lambda function timeout. Didn’t change anything.

I have tried giving the Lambda function all the SNS permissions, thinking it might be a permissions problem, but that didn’t change anything.

If someone has any ideas what could be causing this, and/or what to look at to try to diagnose it, I would greatly appreciate hearing from you. Thanks!

2

Answers


  1. Chosen as BEST ANSWER

    I finally figure out what the problem is. Even though my VPC had an Internet Gateway, you must create a SNS endpoint and when you create it, you must enable "Private DNS names." This requires you to "Enable DNS hostname" on the VPC. In my environment I didn't have "DNS hostname" enabled on my VPC (the default setting), so when I created the endpoint it wouldn't allow me to enable "private DNS names" so I didn't do that. Apparently that is how the Lambda function routes the SNS request to the endpoint, by following the DNS resolution of the endpoint. Once I enabled the two settings, everything worked as expected.


  2. First of all, SNS is like S3 a global service, so you did not need to attach it to your custom VPC on your lambda function to push to an SNS Topic to clarify it 🙂

    I did not know your VPC settings, it can be many things but when you say it’s working on an EC2 instance but not into your Lambda functions it sounds like a VPC issue.

    So what I will try if you do not need the custom VPC on your Lambda for any reasons is to give it a try without that VPC and see what happens.

    Your syntax looks fine so based on your information I will give it a shot, normally I create Lambda and SNS topics from AWS CDK code because its will allow me if i get stuck to get faster help because I can share my infrastructure code so a little tip for you 🙂

    Its required to have the right policy bound to your Lambda function, as default the IAM policy did not have right to something, so find the policy and allow to publish into SNS Topics in general a sample code like this for your policy

    {
      "Statement":[{
        "Effect":"Allow",
        "Action":"sns:Publish",
        "Resource":"*"
      }]
    }
    

    This policy will allow you to use publish into all sns topic, the recommendation when you confirm its working to change the resource with your sns topic arn for secuerty reason.

    Read more about users permissions to publish to SNS Topic here on AWS: https://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.iam.permissions.html

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search