Serverless pattern: accessing public and private resources

Andreas Wittig – 23 Mar 2018

Crossing the chasm between the old world - virtual machines isolated within a private network - and the new world - Serverless making use of publicly accessible APIs only - can be tricky. On the one hand, it is possible to configure VPC access for AWS Lambda. On the other hand, doing so comes with limitations taking away all the fun.

As soon as you are connecting your Lambda function with a VPC, the function is no longer able to access the Internet, even if you are choosing a public subnet with a route to the Internet gateway for your Lambda function (see Internet Access for Lambda Functions to learn more). So you can’t have both: access to resources within your VPC and through the Internet.

To be able to access your VPC as well as the Internet, you need to spin up a NAT Gateway. Or in some cases, you might get away with a VPC Endpoint.

The following example will illustrate the limitation and demonstrate a workaround.

Example: Query a database and publish result to CloudWatch

Let us assume your application stores the sessions of logged in users in a relational database, and you want to monitor the number of active sessions. So, you query your RDS database instance and publish the result to a custom CloudWatch metric periodically. All in all, a perfect use case for a Serverless application as you only need limited compute capacity for a few seconds every five minutes. The following figure shows the involved components:

  • CloudWatch Scheduled Event is triggering the Lambda function every five minutes
  • Lambda Function sends a query to the database and stores the result in the Custom CloudWatch Metric
  • RDS Instance the database storing the active sessions
  • VPC both the RDS instance as well as the Lambda function are placed into a private network
  • NAT Gateway needed, so the Lambda function can access the CloudWatch API (public interface)

Serverless Anti Pattern for accessing public and private resources

On component is taking away all the Serverless fun. Which one?

Problem: NAT Gateway

As shown in the following table the NAT Gateway is a significant cost driver.

Andreas and Michael Wittig

Hej, Andreas & Michael here!

We launched the cloudonaut blog in 2015. Since then, we have published 325 articles: small tips and tricks, best practices, and service reviews. We enjoy writing about all things AWS a lot.

Do you like our blog posts and podcast episodes? Have you learned something new? Consider supporting us create in-depth and independent AWS content. Please help us with a monthly or one-time payment through GitHub Sponsors.

Start supporting us today!
Service Monthly Costs
Lambda (Free Tier) USD 0.00
CloudWatch (Custom Metric) USD 0.40
NAT Gateway USD 32.40

To be fair, that is not a problem if the NAT Gateway is already in place and use by other parts of the infrastructure. Nevertheless, needing to add a NAT Gateway just to be able to store active sessions within a CloudWatch metric is not feasible.

Any idea how to work around the need of a NAT Gateway?

Workaround: Public and Private Lambda Function

Crossing the chasm requires extra creativity. The following figure shows the component allowing you to query data a database and publishing the result to CloudWatch.

  1. The CloudWatch Scheduled Event is triggering the Public Lambda function.
  2. The Public Lambda invokes the Private Lambda synchronously.
  3. The Private Lambda queries the RDS Instance’s database.
  4. The Public Lambda writes the result from the Private Lambda to the Custom CloudWatch Metric.

Serverless Pattern for accessing public and private resources

A 100% Serverless solution, no need for a NAT Gateway anymore.

So, what is the limitation of this workaround? The maximum amount of data passed from the Private Lambda to the Public Lambda is 6 MB.


Whenever a Lambda function needs to access resources inside and outside a VPC, you should think about splitting your tasks into a Lambda function running outside the VPC and a Lambda function running inside the VPC to avoid the need of a NAT Gateway or VPC Endpoint.

Andreas Wittig

Andreas Wittig

I'm an independent consultant, technical writer, and programming founder. All these activities have to do with AWS. I'm writing this blog and all other projects together with my brother Michael.

In 2009, we joined the same company as software developers. Three years later, we were looking for a way to deploy our software—an online banking platform—in an agile way. We got excited about the possibilities in the cloud and the DevOps movement. It’s no wonder we ended up migrating the whole infrastructure of Tullius Walden Bank to AWS. This was a first in the finance industry, at least in Germany! Since 2015, we have accelerated the cloud journeys of startups, mid-sized companies, and enterprises. We have penned books like Amazon Web Services in Action and Rapid Docker on AWS, we regularly update our blog, and we are contributing to the Open Source community. Besides running a 2-headed consultancy, we are entrepreneurs building Software-as-a-Service products.

We are available for projects.

Feedback? Questions? Drop me a line: Email, Twitter, LinkedIn.

Briefcase icon
Hire me