DEV Community

Cover image for How to Deploy DynamoDB with Terraform on AWS
Muhammad Usama Saleem
Muhammad Usama Saleem

Posted on

How to Deploy DynamoDB with Terraform on AWS

How to Deploy DynamoDB Tables on AWS Using Terraform

Infrastructure as Code allows us to define cloud infrastructure using configuration files instead of creating resources manually through the AWS Console.

In this tutorial, we'll use Terraform to create and manage two Amazon DynamoDB tables:

Orders
Products
Enter fullscreen mode Exit fullscreen mode

By the end, you'll have both tables deployed to AWS and managed entirely through Terraform.


🎯 What We Are Building

The final infrastructure will look like this:

Terraform
    │
    ▼
AWS Provider
    │
    ▼
DynamoDB
    ├── Orders
    │   └── OrderId
    │
    └── Products
        └── ProductId
Enter fullscreen mode Exit fullscreen mode

The Orders table will use OrderId as its partition key, while the Products table will use ProductId.


Prerequisites

Before starting, make sure you have:

  • An AWS account
  • Terraform installed
  • AWS credentials configured for Terraform
  • An AWS identity with permissions to create and manage DynamoDB tables

You can verify Terraform is installed with:

terraform version
Enter fullscreen mode Exit fullscreen mode

You should also make sure Terraform can authenticate with AWS before continuing.


📁 Step 1: Create the Terraform Files

Create a directory for the Terraform configuration.

Inside it, create these four files:

terraform/
├── providers.tf
├── variables.tf
├── terraform.tfvars
└── dynamodb.tf
Enter fullscreen mode Exit fullscreen mode

Each file has a specific purpose:

File Purpose
providers.tf Terraform and AWS provider configuration
variables.tf Variable definitions
terraform.tfvars Values for those variables
dynamodb.tf DynamoDB table configuration

Terraform automatically loads all .tf files in the same directory, so there is no need to reference each file individually.


⚙️ Step 2: Configure the AWS Provider

Open providers.tf and add:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }

  required_version = ">= 1.6.0"
}

provider "aws" {
  region = var.aws_region
}
Enter fullscreen mode Exit fullscreen mode

There are two important parts here.

Terraform version

required_version = ">= 1.6.0"
Enter fullscreen mode Exit fullscreen mode

This specifies the Terraform versions supported by the configuration.

AWS provider

required_providers {
  aws = {
    source  = "hashicorp/aws"
    version = "~> 6.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

The AWS provider allows Terraform to communicate with AWS APIs.

The provider is what allows Terraform to create and manage AWS resources such as DynamoDB tables.


🌍 Step 3: Define the Variables

Open variables.tf:

variable "aws_region" {
  type        = string
  description = "The AWS region to deploy resources in"
  default     = "your-aws-region"
}

variable "order_table_name" {
  type        = string
  description = "The name of the DynamoDB order table"
  default     = "Orders"
}

variable "product_table_name" {
  type        = string
  description = "The name of the DynamoDB product table"
  default     = "Products"
}
Enter fullscreen mode Exit fullscreen mode

These variables allow us to keep configuration values separate from our infrastructure definitions.


📝 Step 4: Set the Variable Values

Now open terraform.tfvars:

aws_region         = "your-aws-region"
order_table_name   = "Orders"
product_table_name = "Products"
Enter fullscreen mode Exit fullscreen mode

Replace:

your-aws-region
Enter fullscreen mode Exit fullscreen mode

with the AWS region where you want to deploy the tables.

For example:

aws_region = "us-east-1"
Enter fullscreen mode Exit fullscreen mode

Using variables makes it easier to reuse the same Terraform configuration across different environments or AWS regions.


🗄️ Step 5: Define the DynamoDB Tables

Now we can create the actual DynamoDB infrastructure.

Open dynamodb.tf:

module "dynamodb_order_table" {
  source       = "terraform-aws-modules/dynamodb-table/aws"
  name         = var.order_table_name
  hash_key     = "OrderId"
  billing_mode = "PAY_PER_REQUEST"

  attributes = [
    {
      name = "OrderId"
      type = "S"
    }
  ]
}

module "dynamodb_product_table" {
  source       = "terraform-aws-modules/dynamodb-table/aws"
  name         = var.product_table_name
  hash_key     = "ProductId"
  billing_mode = "PAY_PER_REQUEST"

  attributes = [
    {
      name = "ProductId"
      type = "S"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

We are using the community-maintained:

terraform-aws-modules/dynamodb-table/aws
Enter fullscreen mode Exit fullscreen mode

Terraform module to simplify the DynamoDB configuration.


🧠 Understanding the DynamoDB Configuration

Let's break down the important parts.

source

source = "terraform-aws-modules/dynamodb-table/aws"
Enter fullscreen mode Exit fullscreen mode

This tells Terraform which module to use for creating the DynamoDB table.

Modules allow us to reuse existing Terraform configuration instead of implementing every resource detail ourselves.


name

name = var.order_table_name
Enter fullscreen mode Exit fullscreen mode

This determines the DynamoDB table name.

Because we're using a variable, the name can be changed without modifying the resource configuration.


hash_key

hash_key = "OrderId"
Enter fullscreen mode Exit fullscreen mode

This defines the DynamoDB partition key.

For the Orders table:

OrderId
Enter fullscreen mode Exit fullscreen mode

is the partition key.

For the Products table:

ProductId
Enter fullscreen mode Exit fullscreen mode

is the partition key.


billing_mode

billing_mode = "PAY_PER_REQUEST"
Enter fullscreen mode Exit fullscreen mode

This configures DynamoDB's on-demand capacity mode.

With PAY_PER_REQUEST, we don't need to manually configure provisioned read and write capacity.

This is convenient for workloads where traffic can vary significantly.


attributes

For the Orders table:

attributes = [
  {
    name = "OrderId"
    type = "S"
  }
]
Enter fullscreen mode Exit fullscreen mode

S means the attribute is a string.

The important thing to understand is that DynamoDB does not require us to define every attribute that an item might contain.

For example, an order could look like:

{
  "OrderId": "order-123",
  "CustomerId": "customer-456",
  "ProductId": "product-789",
  "Quantity": 2,
  "OrderStatus": "PENDING"
}
Enter fullscreen mode Exit fullscreen mode

We don't need to declare CustomerId, ProductId, Quantity, or OrderStatus in the Terraform attributes block unless they participate in the table's key schema or indexes.


🔐 Step 6: Make Sure AWS Permissions Are Available

Terraform communicates with AWS through API calls.

Therefore, the AWS identity used by Terraform needs the required DynamoDB permissions.

Depending on the configuration, permissions can include:

dynamodb:CreateTable
dynamodb:DescribeTable
dynamodb:DeleteTable
dynamodb:UpdateTable
dynamodb:TagResource
dynamodb:ListTagsOfResource
Enter fullscreen mode Exit fullscreen mode

The exact permissions required depend on what Terraform needs to create and manage.

The important concept is:

Terraform itself does not bypass AWS permissions. Every AWS operation performed by Terraform is subject to IAM authorization.


🚀 Step 7: Initialize Terraform

Now that the configuration is ready, initialize Terraform.

Run:

terraform init
Enter fullscreen mode Exit fullscreen mode

Terraform will download the required AWS provider and initialize the modules used by the configuration.

You should run terraform init whenever you start working with a new Terraform configuration or when provider/module requirements change.


✅ Step 8: Validate the Configuration

Before deploying anything, validate the Terraform configuration:

terraform validate
Enter fullscreen mode Exit fullscreen mode

If the configuration is valid, Terraform will report:

Success! The configuration is valid.
Enter fullscreen mode Exit fullscreen mode

Validation checks the configuration itself. It does not deploy anything to AWS.


🔎 Step 9: Preview the Deployment

Next, run:

terraform plan
Enter fullscreen mode Exit fullscreen mode

Terraform will calculate the changes required to make the AWS environment match the configuration.

You should see Terraform planning to create the two DynamoDB tables.

Conceptually:

Terraform Configuration
        ↓
    terraform plan
        ↓
Changes Terraform intends to make
Enter fullscreen mode Exit fullscreen mode

This step is extremely important.

Before allowing Terraform to modify infrastructure, review the plan.


🚀 Step 10: Deploy the DynamoDB Tables

Once you're satisfied with the plan, run:

terraform apply
Enter fullscreen mode Exit fullscreen mode

Terraform will display the planned changes and ask for confirmation.

After confirmation, Terraform will create the DynamoDB tables in AWS.

The flow is:

Terraform Configuration
        ↓
terraform plan
        ↓
Review Changes
        ↓
terraform apply
        ↓
AWS DynamoDB
Enter fullscreen mode Exit fullscreen mode

🔍 Step 11: Verify the Terraform Resources

After the deployment completes, you can check the resources Terraform is managing with:

terraform state list
Enter fullscreen mode Exit fullscreen mode

You should see entries corresponding to the two DynamoDB tables, such as:

module.dynamodb_order_table.aws_dynamodb_table.this[0]
module.dynamodb_product_table.aws_dynamodb_table.this[0]
Enter fullscreen mode Exit fullscreen mode

You can also verify the tables directly in the AWS DynamoDB console.

You should now have:

Orders
    Partition Key: OrderId

Products
    Partition Key: ProductId
Enter fullscreen mode Exit fullscreen mode

✅ Step 12: Run Terraform Plan Again

Finally, run:

terraform plan
Enter fullscreen mode Exit fullscreen mode

If everything matches the Terraform configuration, Terraform should report that there are no changes to make.

For example:

No changes. Your infrastructure matches the configuration.
Enter fullscreen mode Exit fullscreen mode

This means Terraform has reached the desired state defined by the configuration.


🏗️ Final Result

We have successfully defined and deployed two DynamoDB tables using Terraform:

                    Terraform
                        │
                        ▼
                 AWS Provider
                        │
              ┌─────────┴─────────┐
              ▼                   ▼
          DynamoDB             DynamoDB
           Orders              Products
              │                   │
        OrderId PK          ProductId PK
Enter fullscreen mode Exit fullscreen mode

The complete workflow is:

Create Terraform files
        ↓
Configure AWS provider
        ↓
Define variables
        ↓
Define DynamoDB tables
        ↓
terraform init
        ↓
terraform validate
        ↓
terraform plan
        ↓
terraform apply
        ↓
Verify resources
        ↓
terraform plan
        ↓
No changes
Enter fullscreen mode Exit fullscreen mode

💡 Key Takeaways

The important concepts from this tutorial are:

  1. Terraform configuration describes the desired infrastructure.

  2. The AWS provider allows Terraform to communicate with AWS.

  3. Terraform modules simplify resource configuration and reuse.

  4. DynamoDB tables can be defined entirely through Terraform.

  5. terraform init prepares the Terraform working environment.

  6. terraform validate checks the configuration.

  7. terraform plan shows what Terraform intends to change.

  8. terraform apply actually creates or modifies AWS infrastructure.

  9. Terraform state tracks the infrastructure Terraform manages.

  10. Running terraform plan after deployment should show no changes when the infrastructure matches the configuration.

The main idea is simple:

Define your AWS infrastructure as code, review the planned changes, and let Terraform create and manage the resources for you.

Top comments (0)