AWS DynamoDB with Terraform: Complete Setup Guide

Published: 2025-08-24
7 min read
Share:

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 table
  • hash_key – Partition key used to uniquely identify items
  • billing_mode – Defines the billing model
  • attribute – 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:

  • vin acts as the partition key
  • S indicates a string attribute type
  • PAY_PER_REQUEST enables 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_name
  • hash_key
  • item

Each attribute must use DynamoDB's typed JSON format.

Example:

{
  "username": {
    "S": "john"
  },
  "age": {
    "N": "30"
  }
}

DynamoDB supports multiple data types including:

  • S – String
  • N – Number
  • BOOL – Boolean
  • B – Binary
  • L – List
  • M – 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.

Free Engineering ToolsNEW

8 free, 100% client-side tools for developers — no signup, no data uploads.

Explore all tools