Two ways to access DynamoDB from private subnets

TOC

Two ways to access DynamoDB from private subnets

There are two ways to access DynamoDB from an EC2 instance in private subnets.

  • NAT Gateway
  • VPC Endpoint (Gateway type)

This page will review how to access DynamoDB tables via the above two.

Environment

Diagram of two ways to access DynamoDB from private subnet.

Create one private subnet in each of the two AZs.

Place an EC2 instance on each subnet.
The instance should be the latest Amazon Linux 2.

Create NAT gateways and gateway type VPC endpoints.
Configure security groups, route tables, etc. to allow each instance to communicate to DynamoDB through them.

This configuration will be built in the ap-northeast-1 (Tokyo) region.

CloudFormation template files

The above configuration is built with CloudFormation.
The CloudFormation template is placed at the following URL

https://github.com/awstut-an-r/awstut-saa/tree/main/03/004

Explanation of key points of template files

NAT Gateway

Resources:
  IGW:
    Type: AWS::EC2::InternetGateway

  IGWAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref IGW

  EIP:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NATGateway:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt EIP.AllocationId
      SubnetId: !Ref PublicSubnet


  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: !Ref CidrIp1
      VpcId: !Ref VPC
      AvailabilityZone: !Sub "${AWS::Region}${AvailabilityZone1}"

  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: !Ref CidrIp2
      VpcId: !Ref VPC
      AvailabilityZone: !Sub "${AWS::Region}${AvailabilityZone1}"

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC

  RouteToInternet:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref IGW

  PublicSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PublicRouteTable

  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC

  RouteToNATGateway:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NATGateway

  PrivateSubnetRouteTableAssociation1:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet1
      RouteTableId: !Ref PrivateRouteTable1
Code language: YAML (yaml)

Create a NAT gateway on the public subnet.
Configure the route table as follows so that instances on the private subnet can communicate with the DynamoDB bucket via the NAT gateway.

  • Route table for private subnets: set default route for NAT gateways
  • Route table for public subnets: set default route for Internet Gateway

VPC endpoints for DynamoDB

Resources:
  GatewayDynamoDBEndpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      RouteTableIds:
        - !Ref PrivateRouteTable2
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.dynamodb"
      VpcEndpointType: Gateway
      VpcId: !Ref VPC

  PrivateSubnet2:
    Type: AWS::EC2::Subnet
    Properties:
      CidrBlock: !Ref CidrIp3
      VpcId: !Ref VPC
      AvailabilityZone: !Sub "${AWS::Region}${AvailabilityZone2}"

  PrivateRouteTable2:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC

  PrivateSubnetRouteTableAssociation2:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet2
      RouteTableId: !Ref PrivateRouteTable2
Code language: YAML (yaml)

To create a gateway type endpoint, specify a route table for the RouteTableIds property.
No special routes need to be specified for the route table.
The routes are automatically registered by associating it with a VPC endpoint.

(Reference) DynamoDB table

Resources:
  Table:
    Type: AWS::DynamoDB::Table
    Properties:
      AttributeDefinitions:
        - AttributeName: Artist
          AttributeType: S
        - AttributeName: SongTitle
          AttributeType: S
      BillingMode: PAY_PER_REQUEST
      KeySchema:
        - AttributeName: Artist
          KeyType: HASH
        - AttributeName: SongTitle
          KeyType: RANGE
      TableClass: STANDARD
      TableName: !Sub "${Prefix}-Music"
Code language: YAML (yaml)

No special settings are made.

The configuration shown in the following official AWS page is exported to a CloudFormation template.

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/getting-started-step-1.html

For basic information on DynamoDB, please refer to the following pages.

あわせて読みたい
Introduction to DynamoDB – Building DB for Review Data 【Building Simple DB for Review Data with DynamoDB】 This is one of the AWS DVA topics related to development with AWS services.As an introduction to DynamoD...

(Reference) EC2 instance

Resources:
  Instance1:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref PrivateSubnet1
          GroupSet:
            - !Ref InstanceSecurityGroup

  Instance2:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Ref ImageId
      InstanceType: !Ref InstanceType
      NetworkInterfaces:
        - DeviceIndex: 0
          SubnetId: !Ref PrivateSubnet2
          GroupSet:
            - !Ref InstanceSecurityGroup
Code language: YAML (yaml)

Place one EC2 instance on each private subnet.

The following are the IAM roles for the instance

Resources:
  InstanceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Action: sts:AssumeRole
            Principal:
              Service:
                - ec2.amazonaws.com
      Policies:
        - PolicyName: AccessS3Policy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - dynamodb:*
                Resource:
                  - !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${Table}"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
Code language: YAML (yaml)

The contents allow all actions on the aforementioned DynamoDB table.

Architecting

Use CloudFormation to build this environment and check its actual behavior.

Create CloudFormation stacks and check the resources in the stacks

Create CloudFormation stacks.
For information on how to create stacks and check each stack, please see the following page.

あわせて読みたい
CloudFormation’s nested stack 【How to build an environment with a nested CloudFormation stack】 Examine nested stacks in CloudFormation. CloudFormation allows you to nest stacks. Nested ...

After reviewing the resources in each stack, information on the main resources created in this case is as follows

  • Instance 1: i-01fc2da5b7f33df18
  • Instance 2: i-0eebb182d0fe97317
  • DynamoDB table: saa-03-004-Music
  • NAT gateway: nat-0568dd9fb3f9fa0ff
  • VPC endpoint: vpce-0ec6434db586081b9

Check each resource from the AWS Management Console.

Check the NAT gateway.

Detail of VPC Endpoint 1.

It has been created successfully.
You can also see that the EIP created with CloudFormation has been successfully attached.

Check the VPC endpoints.

Detail of VPC Endpoint 2.

Indeed, we can see that a gateway type VPC endpoint has been created for DynamoDB.

Operation Check

Access to DynamoDB tables via NAT gateway

Now that we are ready, we access instance 1.
The access will use SSM Session Manager.

% aws ssm start-session --target i-01fc2da5b7f33df18
...
sh-4.2$
Code language: Bash (bash)

For more information on SSM Session Manager, please refer to the following page.

あわせて読みたい
Accessing Linux instance via SSM Session Manager 【Configure Linux instances to be accessed via SSM Session Manager】 We will check a configuration in which an EC2 instance is accessed via SSM Session Manag...

After saving the test item in DynamoDB, check the data in the table.

sh-4.2$ aws dynamodb put-item \
--table-name saa-03-004-Music \
--item '{"Artist": {"S": "aaa"}, "SongTitle": {"S": "AAA"}}' \
--region ap-northeast-1

sh-4.2$ aws dynamodb scan \
--table-name saa-03-004-Music \
--region ap-northeast-1
{
    "Count": 1,
    "Items": [
        {
            "SongTitle": {
                "S": "AAA"
            },
            "Artist": {
                "S": "aaa"
            }
        }
    ],
    "ScannedCount": 1,
    "ConsumedCapacity": null
}
Code language: Bash (bash)

Indeed, we were able to access the DynamoDB tables via the NAT gateway.

Access DynamoDB tables via VPC endpoints

Similarly, use SSM Session Manager to access instance 2.

% aws ssm start-session --target i-0eebb182d0fe97317
...
sh-4.2$
Code language: Bash (bash)

Save and confirm test data as before.

sh-4.2$ aws dynamodb put-item \
--table-name saa-03-004-Music \
--item '{"Artist": {"S": "bbb"}, "SongTitle": {"S": "BBB"}}' \
--region ap-northeast-1

sh-4.2$ aws dynamodb scan \
--table-name saa-03-004-Music \
--region ap-northeast-1
{
    "Count": 2,
    "Items": [
        {
            "SongTitle": {
                "S": "BBB"
            },
            "Artist": {
                "S": "bbb"
            }
        },
        {
            "SongTitle": {
                "S": "AAA"
            },
            "Artist": {
                "S": "aaa"
            }
        }
    ],
    "ScannedCount": 2,
    "ConsumedCapacity": null
}
Code language: Bash (bash)

Indeed, we were able to access the DynamoDB tables via the VPC endpoint.

Summary

We have identified two ways to access S3 from private subnets (NAT gateway and gateway type VPC endpoints).

TOC