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!
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.