Here at DAZN, we use AWS extensively. So choosing DynamoDB as our primary database for user information is a no-brainer. As a streaming service operating in multiple regions around the globe from day 1, we want to provide our millions of users a fluent experience. From registering a new account to logging in, all of them involve database access in one way or another. To guarantee database availability at all time, while keeping the turnaround time low, is nothing short of challenging.
And this, is precisely DA type of problems that AWS DynamoDB Global Table is designed to solve (this would be my last DA-name joke, I promise!).
Provisioning resources for a complex system can be a daunting and error-prone task. Not to mention inevitable changes and maintenance that follows. Traditionally, these kinds of operations would be carried out by an independent Ops team. But here at DAZN, each developer has full ownership over their own systems. Designing, provisioning, implementing, and operating them.
Terraform, as a Infrastructure as Code tool, covers just that. With Terraform, we can expect reproducible infrastructure throughout deployments. It also enables us to track infrastructure changes at code level.
This post will walk you through how to provision DynamoDB global tables with the latest version of Terraform, at this point of writing is v0.11.11.
First of all, let’s see what are the requirements for DynamoDB global table replicas:
- The table must have the same partition key as all of the other replicas.
- The table must have the same write capacity management settings specified.
- The table must have the same name as all of the other replicas.
- The table must have DynamoDB Streams enabled, with the stream containing both the new and the old images of the item.
- None of the replica tables in the global table can contain any data.
- The global secondary indexes must have the same name.
- The global secondary indexes must have the same partition key and sort key (if present).
We can know from the list above, it simply requires us to create identical DynamoDB tables in different regions as global table replicas.
One thing worth mentioning: if you are migrating existing tables to global table, you need to find a way to import data since you would have to create empty replica tables based on #5. Yet the backup/restore feature on AWS only allows you to restore data into a brand new table. So far it’s not possible to restore your data to the global table replicas from a backup. We didn’t have to deal with this thus no further discussion for the rest of the post, but we’d definitely like to know how you resolve it!
Back to the topic, the first step is pretty obvious: we need to create replica tables with the same configuration for each region. Since we’re also setting up the auto-scaling policies, we’ll define these resources in a module for later usage.
main.tf file in a subdirectory
dynamodb-table , we’ll get back to it later. Now, let us define the AWS providers to use for each region. It might be tempting to use the interpolation feature of Terraform to iterate through each region and dynamically create corresponding provider. Unfortunately due to the implementation of Terraform itself, providers can only have static alias.
Lastly, we need to include the modules we defined earlier along with the global table resource itself.
terraform apply these, then you’ll have a fresh DynamoDB global table
we-are-hiring serving 4 different regions.
And that’s it!
With Terraform it’s super easy to define your infrastructure in a developer-readable fashion. You can provision it through a streamlined flow. And all the changes to your infrastrcture are traceable. Terraform is such a game-changer for us. It gives us more control over our infrastructure. That improves our development pipeline drastically.
Interested in seeing how we work first hand? Well, in case you didn’t notice, WE ARE HIRING!
Shout-out to @theburningmonk for reviewing this post!