Monday, October 18, 2021

Create AWS DynamoDB using CloudFormation and a Sample Golang Application



 


In this post we will use CloudFormation to setup a DynamoDB table, and then access it using a sample GO application.


To setup the DynamoDB we will use the following CloudFormation stack.


dynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
BillingMode: PAY_PER_REQUEST
TableName: "my-table"
AttributeDefinitions:
- AttributeName: "mykey"
AttributeType: "S"
KeySchema:
- AttributeName: "mykey"
KeyType: "HASH"


Notice that we specify the key attribute twice. The first time we define its type, which in this case is a string ("S").  The second time we specify that this is a key attribute. Other attributes will be automatically added by the DynamoDB once objects with new attributes are created. An exception for this is a "RANGE" attribute that if it is required, should be also specified here.

The billing mode is "PER REQUEST", which is great if you have no idea about the expected read/write load on the table.


Any other service that accesses the DynamoDB table, should be granted with permissions to access it, for example, to grant an ECS task role permission to access the DynamoDB table use the following rather too permissive  policy. In case of need, limit the actions to a smaller set, e.g:

  • dynamodb.GetItem
  • dynamodb.PutItem
  • dynamodb.Query


taskIamRole:
Type: AWS::IAM::Role
Properties:
RoleName: my-role
AssumeRolePolicyDocument:
Statement:
- Effect: Allow
Principal:
Service: ecs-tasks.amazonaws.com
Action: 'sts:AssumeRole'

taskIamPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: my-policy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- dynamodb:*
Resource: arn:aws:dynamodb:*:*:table/my-table
Roles:
- !Ref taskIamRole



To access the DynamoDB from a GO application, first get a DynamoDB API interface:



import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
)


config := aws.Config{
Region: aws.String("us-east-1"),
}

awsSession, err := session.NewSession(&config)
if err != nil {
panic(err)
}

dynamoDbApi := dynamodb.New(awsSession)



Now we can add items to the DynamoDB using the PutItem API. Notice that we define a structure with the names of the attributes that we want to have in the DynamoDB table.



item:= Item{
Key: "key1",
Data: 123,
}
mappedItem, err := dynamodbattribute.MarshalMap(item)
if err != nil {
panic(err)
}

query := dynamodb.PutItemInput{
Item: mappedItem,
TableName: aws.String("my-table"),
}

_, err = dynamoDbApi.PutItem(&query)
if err != nil {
panic(err)
}



Final Note


While it is not cheap, the AWS DynamoDB supplies an easy API, and great performance for an application. I recommend using it in case your DB API rate is moderate.

No comments:

Post a Comment