3

I am trying to connect to DocumentDB from a Lambda function.

I have configured my DocumentDB as per this tutorial and can access it through the cloud9 command prompt.

The documentDB cluster is part of two security groups. The first security group is called demoDocDB and the second called default and is the vpc defulat security group.

The inbound rules for demoDocDB forward requests from the cloud9 instance to port 27017 where my documentDB database is running.

The inbound rules for the defualt security group specify all traffic, all port ranges and a source of itself. The VPC ID is the default VPC setup.

In lambda when editing the VPC details, I have inputted:

  1. VPC - The defualt VPC
  2. Subnets - Chosen all 3 subnets available
  3. Security Groups - The default security group for VPC

The function has worked twice in writting to the Database, the rest of the time it has timed out, the timeout on the Lambda function is 2 minutes but before reaching that it will throw a time out error.

[ERROR] ServerSelectionTimeoutError: MY_DATABASE_URL:27017: [Errno -2] Name or service not known

The snippet of code below is what is trying to be executed, the function will never reach the print("INSERTED DATA") it times out during the insert statement.

def getDBConnection():
    client = pymongo.MongoClient(***MY_URL***) 

    ##Specify the database to be used
    db = client.test
    print("GOT CONNECTION",db)

    ##Specify the collection to be used
    col = db.myTestCollection
    print("GOT COL",col)

    ##Insert a single document
    col.insert_one({'hello':'Amazon DocumentDB'})
    print("INSERTED DATA")

    ##Find the document that was previously written
    x = col.find_one({'hello':'Amazon DocumentDB'})

    ##Print the result to the screen
    print("RETRIEVED DATA",x)

    ##Close the connection
    client.close()

I have tried changing the version of pymongo as this thread suggested however it did not help.

WK123
  • 620
  • 7
  • 18

1 Answers1

6
  1. Make sure your Lambda function is not in the public subnet, otherwise, it will not work. So, that means you need to go back to the Lambda console and remove the public subnet from the VPC editable section.

  2. Make sure you have a Security group specifically for your Lambda Function as follows:

Lambda Security Group Outbound Rule:

Type            Protocol      Port Range       Destination
All Traffic     All           All              0.0.0.0/0

You can also restrict this to HTTP/HTTPS on Ports 80/443 if you'd like.

2.Check the Security Group of your DocumentDB Cluster to see if it is set up with an inbound rule as follows:

Type            Protocol      Port Range       Source
Custom TCP      TCP           27017            Lambda Security Group
  1. Your Lambda Function needs to have the correct permissions, those are:
    1. Managed policy AWSLambdaBasicExecutionRole
    2. Managed policy AWSLambdaVPCAccessExecutionRole

After doing this your VPC section should look something like this: 1. VPC - The default VPC 2. Subnets - Chosen 2 subnets (Both Private) 3. Security Group for your Lambda function. Not the default security group

And that should do it for you. Let me know if it does not work though and I'll try and help you troubleshoot.

KoalaKey
  • 252
  • 3
  • 11
  • Hey thanks for the reply, still getting a server timeout unfortunately. How do I know if subnets are private or not there is no indication? – WK123 Dec 10 '20 at 11:56
  • I have tried following this also but no luck https://aws.amazon.com/premiumsupport/knowledge-center/internet-access-lambda-function/ – WK123 Dec 10 '20 at 12:49
  • Okay, so you have the correct routes in your route table and an IGW and a NATGW since you followed that. Also, you can check the subnets by copying the subnet ID from the Lambda console and then by going to the subnet section in your VPC console. If however, you did not name/tag your subnets when you created them you will have to check the route tables. If this is the case then the public subnet will be the one associated with the route table that contains the IGW and the private one will be associated with the NATGW. – KoalaKey Dec 10 '20 at 13:02
  • There was a defualt routing table that already existed and it is marked as ```Main``` for the VPC, in it there is the 0.0.0.0/0 destination and the target IGW however there is no subnet association. Did you change the default routing table or leave it alone and create two new ones as in that tutorial? – WK123 Dec 10 '20 at 14:53
  • Another issue could be that you do not have the rds-combined-ca-bundle.pem file in the root of your lambda function. I did not follow that tutorial I built everything from scratch. So, I guess I did build two new ones. But, check for that pem file before you start changing anything else in the VPC configs. – KoalaKey Dec 10 '20 at 15:21
  • Have the pem file in the root directory, it was complaining before with a different error when it wasn't in the root so don't think that is the case. When you say you built from scratch did you follow any tutorial or steps? Just trying to replicate – WK123 Dec 10 '20 at 15:48
  • Ok I got it working by deleting the cluster and cloud9 stack and restarting. Instead of setting up cloud9 I just set up the the DB Cluster and the lambda function to it and it works. The private subnets are setup as in that document. Can two services, cloud 9 and lambda share subnets do you know? – WK123 Dec 10 '20 at 16:01
  • 1
    Nope, just built everything from the ground up from the knowledge I've gained from working with AWS. I did not follow any tutorials or anything of that nature. I think your problem is somewhere in the networking. I am working on a project right now pulling data from an API and utilizing DocumentDB as the data store and documenting it all so when I finish I'll post the link here that way if you still can't get yours to work you can check out what I did and replicate it. Should be done by Sunday. Let me know if you figure out the isue, I'll comment here if i think of anything else – KoalaKey Dec 10 '20 at 16:07
  • Oh okay cool, Yes they can share subnets. – KoalaKey Dec 10 '20 at 16:10
  • That would be helpful, tried to connect my cloud9 back up to use Mongo Shell and now the cloud9 is not connecting haha it is defaulting to one of the private subnets created for lambda. I am using one security group for DocumentDB which allows traffic from lambda and cloud9 on same port 27017, Im not sure if that would be a problem – WK123 Dec 10 '20 at 16:14
  • Ok, cloud 9 working and lambda working now, cloud 9 needed to be in the public subnet for the instance I was creating. So http->Cloud9->Ec2->DocumentDB. The lambda function is inside the vpc of the database so has private subnet. Going to mark this as the answer you've been big help, anyone else out there go through this video https://www.youtube.com/watch?v=fpxDGU2KdkA – WK123 Dec 11 '20 at 11:08