logo
VPC Endpoints: an alternative to NAT Gateway

VPC Endpoints: an alternative to NAT Gateway

How to create VPC endpoints with AWS CDK to reduce infrastructure costs on AWS

Published Jan 17, 2024

The task to build a container based application on AWS using services such as AWS ECS, AWS Fargate and AWS VPC is a challenge in many ways, especially about the infrastructure costs.

The most recommended approach is to create a VPC with a NAT Gateway. In this way, the instances of your application will be on a private subnetwork, securely isolated from the Internet, only accessible by the port configured in the security group, through an Application Load Balancer, at minimum.
The following simplified diagram illustrates this scenario:
VPC with NAT Gateway
VPC with NAT Gateway
If the application instances, on the AWS ECS, needs to access other AWS resources, such as DynamoDB tables or SNS topics, this access will be made using the NAT Gateway.
Thanks to AWS CDK, the task to build the VPC and most of the required componentes to host this kind of application, is relatively easy, as describe in the following code:
1
2
3
4
this.vpc = new Vpc(this, "Vpc", VpcProps.builder()
.vpcName("Vpc")
.maxAzs(2)
.build());
These lines will create the VPC itself, with two availability zones, private subnetworks, public subnetworks and the NAT Gateway. Everything configured as they must be in terms of security, availability and resilience.
Now, the not so good story. The NAT Gateway, which is created per availability zone, is an expensive resource, charged per hour and traffic.
I am not complaining. Particularly, I use this approach on my courses and projects. But I decided to search for an alternative solution, at least for some scenarios.

The usage of VPC Endpoints for the describe scenario can be an alternative to NAT Gateway, keeping the application instances in a private subnetwork, equally isolated from the Internet, and accessing other AWS resources.
The following simplified diagram illustrates this scenario:
Using VPC Endpoint instead of NAT Gateway
Using VPC Endpoint instead of NAT Gateway
Each type of AWS resource that needs to accessed by the application needs a VPC Endpoint.
The VPC Endpoint is also a resource charged per hour and traffic, but is cheaper than the NAT Gateway.
And there is another advantage, the VPC Endpoint to access S3 buckets has no cost.
The following code creates a VPC, with two VPC Endpoints, to access S3 buckets and DynamoDB tables.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Map<String, GatewayVpcEndpointOptions> gatewayEndpoints = new HashMap<>();
gatewayEndpoints.put("S3", GatewayVpcEndpointOptions.builder()
.service(GatewayVpcEndpointAwsService.S3)
.build());
gatewayEndpoints.put("DYNAMODB", GatewayVpcEndpointOptions.builder()
.service(GatewayVpcEndpointAwsService.DYNAMODB)
.build());

this.vpc = new Vpc(this, "Vpc", VpcProps.builder()
.vpcName("Vpc")
.maxAzs(2)
.natGateways(0)
.gatewayEndpoints(gatewayEndpoints)
.build());
The natGateway attribute defines that there is no NAT Gateway to be created.
The gatewayEndpoints attribute receives the VPC Endpoints.
Following the same pattern, to access ECR repositories, it's necessary to create two types of VPC Endpoints, as explained in the following code:
1
2
3
4
5
6
this.vpc.addInterfaceEndpoint("EcrDockerEndpoint", InterfaceVpcEndpointOptions.builder()
.service(InterfaceVpcEndpointAwsService.ECR_DOCKER)
.build());
this.vpc.addInterfaceEndpoint("EcrApiEndpoint", InterfaceVpcEndpointOptions.builder()
.service(InterfaceVpcEndpointAwsService.ECR)
.build());
Another example is to access the CloudWatch Logs API, to let the application instance injects logs on it. Also, the following code shows how to create a VPC Endpoint to access SNS topics.
1
2
3
4
5
6
this.vpc.addInterfaceEndpoint("CWApiEndpoint", InterfaceVpcEndpointOptions.builder()
.service(InterfaceVpcEndpointAwsService.CLOUDWATCH_LOGS)
.build());
this.vpc.addInterfaceEndpoint("SnsEndpoint", InterfaceVpcEndpointOptions.builder()
.service(InterfaceVpcEndpointAwsService.SNS)
.build());
This solution can be a little bit difficult to build, because every AWS resource that need to be accessed needs to have an VPC Endpoint properly configured. A special case is the ECR repository.
It's easy to just forgot to create this VPC Endpoint if your application will access a new AWS resource, specially if there are different teams responsible for the VPC and for application infrastructure itself.

There are some situations where the NAT Gateway usage can be cheaper than the VPC Endpoints. If your application needs to access several AWS resources, the overall cost of required VPC Endpoints can be more expensive than the NAT Gateway.
To help you, here is the link with the pricing information about the VPC Link.
And here, the link with the pricing information about the NAT Gateway.

Even with the complexity to build the infrastructure using VPC Endpoints, comparing to NAT Gateway, it's not a hard job if you're using the AWS CDK.
The VPC Endpoint can be a cheaper solution for applications which needs to access a few AWS services.
To finish, the decision between VPC Endpoints and NAT Gateway depends of your application. Probably you can have a technical requirement where the NAT Gateway is the best solution, even if it is more expensive.