How to: AWS Service Endpoint for S3 / DynamoDB

AWS & Terraform

This Again?

A few months back I published an article reviewing the different ways to pass traffic between a Lambda in a private subnet and a Lambda in a public subnet. In that article the best solution was to use a VPC Service Endpoint. `So why another article about the same thing?` you might be asking. Well, S3 and DynamoDB leverage Service Endpoints a bit differently. Since I recent impliment an S3 Service Endpoint I wanted to document the differences here.

If you are interested in how to implement Service endpoints for any service other than DynamoDB and S3, checkout the other post here.

Now, on with the show!

The concept here is the same as a regular VPC Service Endpoint. With S3 / Dynamo the connection is via a Gateway type, not an Interface type like all the others. The Interface connection gets an associations with an subnet. The Gateway type gets an associations with a route table.

Terraform, yea baby!

resource aws_vpc_endpoint s3 {
  service_name        = join(".", ["com.amazonaws", var.region, "s3"])
  vpc_endpoint_type   = "Gateway"
  vpc_id              =

  tags = merge(
      Name = join(var.delimiter, [, var.stage, "gateway-endpoint-for-s3",])
      Tech = "Service Endpoint"
      Srv  = "VPC"

## VPC Endpoint Route Table association
resource aws_vpc_endpoint_route_table_association s3_vpc_endpoint_private_one {
  route_table_id  =
  vpc_endpoint_id =

The check if the association is correct check your route table

And that is about it. Not drastically different from Service Endpoint that are ‘Interfaces’. But it is important to know the difference when the need is to keep all the service traffic private.

Additional Resources