We are using CloudFormation for defining our infrastructure. A global dynamodb table is used that is defined and created in one region (the primary region), but has replicas in another region. How do I reference this same table in the template in another region? Specifically I need to get the global table name and stream ARN for the stack in secondary region. Reason? One lambda of this stack from secondary region uses this name and stream ARN to create new records for this table.
I thought anyone using global tables will encounter this, but I searched on Internet and couldn’t find any easy solution.
Here’s how it’s defined in the template right now:
Table1:
Type: AWS::DynamoDB::GlobalTable
Condition: CreateGlobalTable
Properties:
TableName: !Sub "Table1-${StageName}"
AttributeDefinitions:
- AttributeName: store_id
AttributeType: S
- AttributeName: client_name
AttributeType: S
BillingMode: PAY_PER_REQUEST
KeySchema:
- AttributeName: store_id
KeyType: HASH
- AttributeName: client_name
KeyType: RANGE
StreamSpecification:
StreamViewType: NEW_IMAGE
Replicas:
- Region: us-east-1
- Region: us-west-2
TimeToLiveSpecification:
AttributeName: time_to_live
Enabled: true
2
Answers
You need a custom resource for that. So it will be a lambda function that will get what you need, and return it to your template.
I ran into the exact same problem. With the help of this blog entry, I came up with the following solution using a custom resource.
In short, I split my stack into 2: In one I deploy the
DynamoDB::GlobalTable
, along with aServerless::Function
which will be in charge of getting the stream ARN for us. In the other, I have the rest of components.The template for the first stack looks as follows:
The code for the Lambda is the following (note you need to pack the
crhelper
dependency along the Lambda).Then, in the second stack, we need to create the custom resource.
Finally, you can get/reference the stream ARN in the replica regions (in the second stack template) through:
Some notes about this solution:
return stream_arn
in thecreate(...)
function of the Lambda.Resource: '*'
). However, there you cannot reference theDynamoTable
resource since it will not exist in the replica regions. If anyone knows a better way to just restrict it to that table, please let me know.