AWS DynamoDB with Terraform: Complete Setup Guide
AWS DynamoDB with Terraform allows you to provision and manage NoSQL database infrastructure using Infrastructure as Code (IaC). Instead of manually creating tables through the AWS Management Console, you can define DynamoDB resources in code, version them in Git, and deploy them consistently across multiple environments.
This approach is widely used by DevOps engineers, platform teams, and software developers building serverless applications, microservices, and event-driven systems on AWS.
If you're new to Terraform, start with our guide on Getting Started with Terraform and AWS before creating DynamoDB resources.
Why Use AWS DynamoDB with Terraform?
Managing DynamoDB resources through Terraform provides several advantages:
- Version-controlled infrastructure definitions
- Repeatable deployments across environments
- Reduced manual configuration errors
- Easier collaboration between team members
- Automated infrastructure provisioning through CI/CD pipelines
In real-world environments, Terraform helps ensure that development, staging, and production DynamoDB configurations remain consistent.
Many teams adopt a DynamoDB Terraform workflow because infrastructure changes can be reviewed through pull requests before deployment, reducing the risk of configuration drift.
Prerequisites
Before creating a DynamoDB table with Terraform, make sure you have:
- An AWS account
- Terraform installed locally
- AWS credentials configured
- Basic understanding of Terraform resources
If Terraform is not installed yet, refer to our guide on Installing Terraform.
You can find the latest AWS provider documentation in the official Terraform Registry.
How to Create a DynamoDB Table Using Terraform
Terraform provides the aws_dynamodb_table resource for creating and managing DynamoDB tables.
The most important arguments include:
name– Name of the DynamoDB tablehash_key– Partition key used to uniquely identify itemsbilling_mode– Defines the billing modelattribute– Defines key attributes used by the table
Basic DynamoDB Table Example
The following example creates a DynamoDB table named cars using on-demand billing:
resource "aws_dynamodb_table" "cars" {
name = "cars"
hash_key = "vin"
billing_mode = "PAY_PER_REQUEST"
attribute {
name = "vin"
type = "S"
}
}
In this example:
vinacts as the partition keySindicates a string attribute typePAY_PER_REQUESTenables on-demand billing
A common mistake is defining attributes that are not used in keys or indexes. DynamoDB only requires attributes that participate in the primary key or secondary indexes.
Pro Tip
For most new applications, PAY_PER_REQUEST is the simplest choice. It automatically scales capacity and removes the need to estimate read and write throughput requirements.
Complete AWS DynamoDB Terraform Example
The following configuration creates a DynamoDB table and inserts a sample record.
provider "aws" {
region = "us-east-1"
}
resource "aws_dynamodb_table" "cars" {
name = "cars"
hash_key = "vin"
billing_mode = "PAY_PER_REQUEST"
attribute {
name = "vin"
type = "S"
}
}
resource "aws_dynamodb_table_item" "car_data" {
table_name = aws_dynamodb_table.cars.name
hash_key = "vin"
item = <<ITEM
{
"vin": {
"S": "1HGCM82633A004352"
},
"make": {
"S": "Honda"
},
"model": {
"S": "Accord"
},
"year": {
"N": "2020"
}
}
ITEM
}
After running:
terraform init
terraform plan
terraform apply
Terraform will create the table and insert the sample item.
For a detailed explanation of Terraform commands, see our guide on Terraform Commands Explained.
Choosing Between Provisioned and On-Demand Billing
DynamoDB supports two billing models.
Provisioned Capacity
With provisioned capacity, you explicitly define:
- Read capacity units (RCUs)
- Write capacity units (WCUs)
This model is typically used when workloads are predictable and capacity requirements are known in advance.
On-Demand Capacity
With PAY_PER_REQUEST:
- No capacity planning is required
- AWS automatically scales throughput
- You pay only for actual requests
Most proof-of-concept projects, development environments, and applications with unpredictable traffic patterns start with on-demand billing.
For current billing details, refer to the official Amazon DynamoDB documentation.
How to Insert Items into a DynamoDB Table
Terraform provides the aws_dynamodb_table_item resource for inserting records into an existing table.
The required arguments include:
table_namehash_keyitem
Each attribute must use DynamoDB's typed JSON format.
Example:
{
"username": {
"S": "john"
},
"age": {
"N": "30"
}
}
DynamoDB supports multiple data types including:
S– StringN– NumberBOOL– BooleanB– BinaryL– ListM– Map
When working with DynamoDB with Terraform, understanding these data types is important because Terraform passes item definitions directly to the DynamoDB API.
Limitations of Managing Data with Terraform
While Terraform can insert records into DynamoDB tables, it is not designed for large-scale data operations.
Terraform works best for managing:
- Tables
- Keys
- Secondary indexes
- Autoscaling configurations
- Encryption settings
- IAM permissions
Terraform is generally not the right tool for:
- Bulk data imports
- Application-generated data
- High-volume transactional workloads
Most production teams use SDKs, ETL pipelines, migration tools, or application code for data loading.
Operational Consideration
Every item managed through Terraform becomes part of the Terraform state file. Large datasets can significantly increase state size and make deployments more difficult to manage.
Configuring Primary Keys, Sort Keys, and Attributes
DynamoDB tables can use:
- Partition key only
- Partition key and sort key
A partition key groups related data, while a sort key enables efficient querying within that partition.
Example with a Sort Key
resource "aws_dynamodb_table" "vehicles" {
name = "vehicles"
billing_mode = "PAY_PER_REQUEST"
hash_key = "vin"
range_key = "registration_date"
attribute {
name = "vin"
type = "S"
}
attribute {
name = "registration_date"
type = "S"
}
}
Many production applications use composite keys because they support more flexible query patterns while maintaining high performance.
Working with Secondary Indexes
Terraform also supports:
- Global Secondary Indexes (GSI)
- Local Secondary Indexes (LSI)
Secondary indexes allow additional query patterns without changing the table's primary key design.
Before adding indexes, spend time designing access patterns carefully. DynamoDB performance depends heavily on choosing the correct key structure.
You can review the latest indexing capabilities in the official AWS DynamoDB Developer Guide.
Terraform Best Practices for DynamoDB Deployments
As your infrastructure grows, follow these practices:
- Use modules for reusable configurations
- Store environment-specific values in variables
- Separate development, staging, and production deployments
- Use remote state storage
- Protect critical resources from accidental deletion
For reusable infrastructure patterns, read:
For production environments, configure remote state storage using AWS S3 with Terraform.
Teams managing multiple DynamoDB tables should also use Terraform Remote Backends on AWS S3 to improve collaboration and avoid state conflicts.
Preventing Accidental DynamoDB Deletions
Critical databases should be protected from unintended destruction.
Terraform provides the prevent_destroy lifecycle rule:
resource "aws_dynamodb_table" "cars" {
name = "cars"
hash_key = "vin"
billing_mode = "PAY_PER_REQUEST"
lifecycle {
prevent_destroy = true
}
attribute {
name = "vin"
type = "S"
}
}
This configuration prevents Terraform from deleting the table unless the protection is explicitly removed.
For a deeper understanding, see our guide on Terraform Lifecycle Rules.
Conclusion
AWS DynamoDB with Terraform provides a reliable way to manage NoSQL database infrastructure through code.
By defining tables, keys, indexes, and configuration settings in Terraform, teams can deploy consistent infrastructure, reduce manual effort, and maintain version-controlled database configurations.
Terraform is excellent for provisioning DynamoDB resources. For application data and large-scale data ingestion, dedicated data pipelines and AWS SDKs remain the preferred approach.
Frequently Asked Questions (FAQs)
Can I manage large datasets in DynamoDB using Terraform?
No. Terraform is intended for infrastructure management rather than large-scale data operations. Bulk data loading is typically handled through applications, SDKs, or migration tools.
Is on-demand billing better than provisioned capacity?
It depends on workload patterns. On-demand billing is ideal for unpredictable traffic, while provisioned capacity is often more cost-effective for steady workloads.
Can Terraform create DynamoDB secondary indexes?
Yes. Terraform supports both Global Secondary Indexes (GSI) and Local Secondary Indexes (LSI).
What format does DynamoDB require for item data?
DynamoDB expects typed JSON values such as:
{
"name": {
"S": "John"
},
"age": {
"N": "30"
}
}
How do I prevent accidental DynamoDB table deletions?
Use the prevent_destroy lifecycle rule:
lifecycle {
prevent_destroy = true
}
This prevents Terraform from destroying the resource unless the protection is intentionally removed.
8 free, 100% client-side tools for developers — no signup, no data uploads.
Explore all tools