Update an Existing DynamoDB Table Resource to be a GlobalTable Resource

Joel Seeger
Jamf Engineering
Published in
5 min readJun 10, 2022

--

Our team needed to move to a multi-region configuration in AWS in order to provide better performance for our customers in other parts of the world and to provide additional redundancy for our DynamoDB tables and our artifacts stored in S3. A migration of our typical DynamoDB tables to global tables in CloudFormation was needed and it seemed there had to be an easier way than scripting out a backup and restore process. Thus, the challenge was to find that “easier” way and this is what we came up with…

The following will allow you to change an existing AWS::DynamoDB::Table to be an AWS::DynamoDB::GlobalTable. With this process you don’t have to create a new table and then export from the old table and then import into the new global table via a script. Consider it a migration from a regular table to a global table without disrupting the underlying table/data.

As we step through this we’ll use the AWS console and CloudFormation templates.

I’ve created a simple stack with a very rudimentary table of type AWS::DynamoDB::Table. Here’s our template and what things are looking like after our deploy…

AWSTemplateFormatVersion: 2010-09-09
Description: Dynamo Table to GlobalTable migration CloudFormation template

Resources:

# Dynamodb Tables
MyCoolTable:
Type: AWS::DynamoDB::Table
DeletionPolicy: Retain
Properties:
TableName: MyCoolTable
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH

Deletion Policy of Retain is Required

Ensure the table resource has a DeletionPolicy of Retain so it won’t be removed when deleting the stack. If it doesn’t, update your CloudFormation and redeploy.

MyCoolTable:
Type: AWS::DynamoDB::Table
DeletionPolicy: Retain
Properties:
TableName: MyCoolTable

This will leave your table in your account but orphaned from the stack.

I know an unintended stack delete will never happen to you but using “Retain” provides that additional safety net and is an overall good practice.

Delete Your Database Stack

Prior to deleting your stack, it’s recommended you create a backup of your table “just in case”.

It’s recommended your database stack be separate from other resources. Aside from reducing the complexity of managing a single stack, putting like resources in a single stack allows you to make changes without impacting other resources.

While your stack may be gone, your DynamoDB table and its data still exists.

Change DynamoDB Type to GlobalTable

Update your CloudFormation template to make it a global table.

AWSTemplateFormatVersion: 2010-09-09
Description: Dynamo Table to GlobalTable migration CloudFormation template

Resources:

# Dynamodb Tables
MyCoolTable:
Type: AWS::DynamoDB::GlobalTable
DeletionPolicy: Retain
Properties:
TableName: MyCoolTable
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
Replicas:
- Region: !Ref AWS::Region
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true
StreamSpecification:
StreamViewType: NEW_IMAGE

The table you want to change should now have the following:
Type: AWS::DynamoDB::GlobalTable

You’ll also need the Replicas section. A key thing to note is you can only specify your “main” replica. Additional replicas need to be added one at a time if you add your replicas by updating your stack via the console or by deploying command line.

Replicas: 
- Region: !Ref AWS::Region
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true

Global tables require streams to be enabled and, therefore, a StreamSpecification is required.

StreamSpecification: 
StreamViewType: NEW_IMAGE

Recreate Your Database Stack

Recreate your stack via the console, within CloudFormation → Stacks, select “Create stack” → “With existing resources (Import resources)”.

Specify your updated template and select “Next”.

Provide identifier values for the resources you wish to import. In this example, it’s MyCoolTable.

Select “Next” and add your stack name.

After selecting “Next” you’ll get a summary of what the import will do…

Scroll down and you’ll see what changes will be made. After you verify the changes, select “Import resources”.

Your stack will be updated…

And your table will now be a GlobalTable…

Add Replicas

To add a replica (again — only one at a time), update your template and redeploy or update the stack via the console with your updated template.

Replicas:
- Region: !Ref AWS::Region
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true
- Region: 'ap-southeast-2'
PointInTimeRecoverySpecification:
PointInTimeRecoveryEnabled: true

The replica now exists…

Hopefully this tutorial helps ease the migration process to a global table.

Thanks to Bryson Tyrrell for the much needed support in this endeavor.

--

--