Lambda time out on SQS sending message

Viewed 252

I set up a very simple Lambda for sending a message to a SQS. Lambda is in a VPC, with two public subnets (I do not fully understand aws networking, I've just seen that the routing table connected to subnets have 0.0.0.0/0 as one the routes, connected to Internet Gateway) and a security group. I've already double-checked Permissions and they work properly, cause if I remove VPC settings on Lambda it works.

I tried to create an Endpoint as suggested in the article: SQS sending from VPC, but the Lambda timed out.

As suggested in SO solution link, I tried to add the endpoint_url in the client, also that's not working.

Lambda code is the following:

#Testing SQS push message.
import botocore
import boto3

def main(event, context):
    session = boto3.Session()

    sqs_client = session.client(
        service_name='sqs',
        endpoint_url='https://sqs.eu-west-1.amazonaws.com',
    )

    sqs_client.send_message(
        QueueUrl='https://sqs.eu-west-1.amazonaws.com/***********/tutorial-queue-test',
        MessageBody='msg sent from '
    )

    return {}

Resuming my setup I have:

  • Lambda inside a VPC, 2 subnets(public), 1 security group.
  • SQS
  • SQS Endpoint inside the VPC

I cannot keep the Lambda outside the VPC, cause I'll need to use a EFS, that I will integrate in the Lambda.

SOLUTION: Afterall I succeded to launch correctly the Lambda, I guess it was a mix of bad security group rules, both for Lambda and Endpoint, and VPC private DNS name disabled. Thanks everyone for the support.

Just for readability purposes I summerise the main solutions that brought me to successfully launch Lambda:

  • Add a Security Group for Lambda, which has INBOUND RULE(Protocol:All TCP, Ports:0 - 65535, Source:0.0.0.0/0) and OUTBOUND RULE(Protocol:All, Ports:All, Destination:0.0.0.0/0)
  • Add a Security Group for Endpoint, which has INBOUND RULE(IP version: –, Type:All TCP, Protocol:TCP, Ports:0 - 65535, Source: <INSERT_LAMBDA_SECURITY_GROUP>) and OUTBOUND RULE(IP version: IPv4, Type:All traffic, Protocol:All, Ports:All, Destination: 0.0.0.0/0).
  • From Endpoints, select the current Endpoint->Actions->Modify private DNS name-> Enable private DNS names.
1 Answers

Lambdas placed in a Public subnet do not have internet connectivity as they cannot use an Internet Gateway.

So the first step is to place the lambda in a Private or Isolated subnet, according to best practices.

Then, there are two options:

  1. If your Lambda requires internet connectivity, add a NAT gateway and add a route to it from the Private subnet. If you go this route, you will not need to use VPC endpoints.

  2. If you want to avoid using a NAT gateway, simply place the lambda in an Isolated subnet and it will use the VPC endpoints you created.

If the endpoints have private DNS enabled, you do not need to provide a custom endpoint_url, boto3 will work as is.

If this doesn't work, verify that the endpoint is created in the subnet that your Lambda is using. Also verify that you have Private DNS turned on for the endpoint.

See also: Why can't an AWS lambda function inside a public subnet in a VPC connect to the internet?

Related