Access DynamoDB and S3 using AWS Lambda Functions inside VPC

In general, if we want to perform read/write operations in DynamoDB using AWS Lambda function, for this to achieve we don’t need to worry about the connectivity between the AWS services. We only just need to create a read/write policy and assign in to Lambda execution Role. Below is common Cloudformation of the Lambda function.

PostFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref dynamoDbTableName
Runtime: nodejs12.x
CodeUri: src/...

What if, your Lambda function will use other AWS resources which aren’t accessible from the public internet ? For this purpose we need to run the Lambda function into VPC.

How can we execute the Lambda function into the VPC ? Please refer the code section below. We have added the vpcConfig block into the cloud formation and it contains mainly subnetIds and Security group

PostFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Policies:
- DynamoDBCrudPolicy:
TableName: dynamoDbTableName
Runtime: nodejs12.x
CodeUri: src/...
VpcConfig:
SecurityGroupIds:
- !Ref SecurityGroup
SubnetIds: !Ref Subnets
SecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: security group for Lambda in VPC
GroupDescription: Manages the access to and from the EC2 ins.
VpcId: !Ref VpcId
SecurityGroupEgress:
- Description: Egress port of the http
IpProtocol: tcp
CidrIp: 0.0.0.0/0
FromPort: 80
ToPort: 80
- Description: Egress port of the https
IpProtocol: tcp
CidrIp: 0.0.0.0/0
FromPort: 443
ToPort: 443

Well, now we have added the Lambda into the VPC. Should Lambda will be able to access the DynamoDB? Answer is no. Why?

By default, Lambda runs your functions in a secure VPC with access to AWS services and the internet. Lambda owns this VPC, which isn’t connected to your account. When you connect a function to a VPC in your account, the function can’t access the internet.

Now we are known to the problem, How we will provide the internet access? We have two ways to do it.
1. Using NAT Gateways
2. Using VPC endpoints ( Gateway & Interface)

Gateway endpoint (DynamoDB and S3 only): A gateway that is a target for a specific route in your route table, used for traffic destined to a supported AWS service which is either DynamoDB or S3.

Interface endpoint (Other than DynamoDB and S3): An Interface endpoint is an elastic network interface with a private IP address from the IP address range of your subnet. It serves as an entry point for traffic destined to a supported AWS service or a VPC endpoint service. Interface endpoints are powered by AWSPrivateLink.

So finally, we need to create the Gateway VPC endpoint to access the internet. Please refer below IACs for DynamoDB And S3 to create the endpoints.

For S3:

S3Endpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal: "*"
Action:
- "s3:*"
Resource:
- "*"
RouteTableIds:
- !Ref privateRouteTable
ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
VpcId: !Ref privateVPC

For DynamoDB:

dynamoDBEndpoint:
Type: AWS::EC2::VPCEndpoint
Properties:
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal: "*"
Action:
- "dynamodb:*"
Resource:
- "*"
RouteTableIds:
- !Ref privateRouteTable
ServiceName: !Sub com.amazonaws.${AWS::Region}.dynamodb
VpcId: !Ref privateVPC

Now, you will be able to connect to the DynamoDB and S3 using VPC Gateway endpoints through Lambda functions.