Connecting to mongodb atlas/external service from Google cloud functions via static IP address

sharath chandra
3 min readMay 18, 2020

--

I am using google cloud functions for variety of background jobs, batch based ETL jobs etc.

Accessing the database on these jobs are much easier and faster than working via API’s. Accessing the database directly from cloud functions means that we will need to allow all incoming traffic (0.0.0.0), since cloud functions don’t have static IP. This would freak out database administrator !!!

To workaround this problem we can leverage

Couple things about our infra

  • We don’t have a separate VPC for our application, instead using the default VPC of google cloud
  • The main application and web traffic are hosted on the asia regions
  • The database is also hosted on the asia region (same as application)
  • The cloud functions are hosted on the us-central1 since the they aren’t available yet in the local region

Step 1 : Cloud function

I have written a small sample cloud function to check mainly 2 things

  • Can the function access external API ?
  • Is there is a static IP for the cloud function ?

I am using standard external services to verify the above. If above 2 are working as expected, then we should be able to access mongodb database on atlas or any other external accessible service

const simpleExternalAPIAccess = functions.https.onRequest(async (request, response) => {
const result = await axios.get("https://jsonplaceholder.typicode.com/todos/1");
const resultIP = await axios.get("https://api.ipify.org/?format=json")
response.send({
data: JSON.stringify(result.data),
ip: JSON.stringify(resultIP.data)
});
});

Step 2 : Configuring Serverless VPC

Create a serverless VPC connector via console/shell. Ensure that this VPC connector is created in the region of the cloud functions.

Detailed documentation for this is available @ https://cloud.google.com/vpc/docs/configure-serverless-vpc-access#creating_a_connector

gcloud compute networks vpc-access connectors create [CONNECTOR_NAME] \
--network [VPC_NETWORK] \
--region [REGION] \
--range [IP_RANGE]
e.g.gcloud compute networks vpc-access connectors create knowledgefactory-taskhub-us-central1
--network default \
--region us-central1 \
--range 10.8.0.0

Step 3: Configure the cloud functions to use the VPC connector

The cloud functions needs to be updated to use the VPC connector. This again can be done via UI or gcloud. Check https://cloud.google.com/functions/docs/networking/connecting-vpc#configuring

gcloud functions deploy helloWorld \
--vpc-connector <full path of connector>

* If you are using firebase-tools for deployment of cloud functions, unfortunately firebase-tools do not have ability to add vpc connector

Step 4 : Configure Cloud NAT

Step 1 and 2 ensure that there is a VPC connector configured, however its the NAT which allows for all the traffic to be routed. We can have ingress and egress rules configured for the cloud NAT.

Ensure that Cloud NAT is created in the same region as the VPC connector. In the above case I am creating it at “us-central1”.

Detailed documentation is available at https://cloud.google.com/nat/docs/using-nat

gcloud compute routers nats create nat-config \
--router=knowledgefactory-router \
--nat-external-ip-pool=<ip_addressses>

Once the above steps are done, cloud functions will be able to access any external traffic using the static ip address

Step 5: Verify running the cloud function written in step 1

  • Run the cloud function via console/ui

The response will be something like

{
"data": {
"userId":1,
"id":1,"title":"delectus aut autem",
"completed":false
},
"ip": { "ip": <public_ip_address_configured_in_nat>}
}
  • check that you get to access the external api
  • check that you get to see the static IP address in the response

Step 6 : Configure mongodb atlas to allow incoming traffic from the static IP address

  • Login to mongodb atlas console
  • Navigate to the networking under the cluster and ensure that the static IP address configured in cloud NAT is whitlisted

That’s it, we are done. Now we should be able to access the mongodb or for that matter any external service via static ip address.

--

--