AWS for DevOps — DynamoDB for DevOps

2 minute read

9.3 — DynamoDB for DevOps

Amazon DynamoDB is a fully managed NoSQL database with single-digit millisecond performance at any scale. For DevOps, it’s the go-to database for serverless backends, Terraform state locking, and event-driven pipelines.

Key Concepts

Concept Description Analogy
Table Collection of items A spreadsheet
Item A single record (row) A row in the spreadsheet
Attribute A field on an item A column value
Partition Key (PK) Primary identifier — must be unique Employee ID
Sort Key (SK) Optional — enables range queries Date, version number

Creating a Table

$ aws dynamodb create-table \
    --table-name Deployments \
    --attribute-definitions \
        AttributeName=ServiceName,AttributeType=S \
        AttributeName=DeploymentId,AttributeType=S \
    --key-schema \
        AttributeName=ServiceName,KeyType=HASH \
        AttributeName=DeploymentId,KeyType=RANGE \
    --billing-mode PAY_PER_REQUEST \
    --tags Key=Team,Value=DevOps
{
    "TableDescription": {
        "TableName": "Deployments",
        "TableStatus": "CREATING",
        "BillingModeSummary": { "BillingMode": "PAY_PER_REQUEST" }
    }
}

On-Demand vs Provisioned

Mode Pricing Scaling Best For
On-Demand Per request ($1.25/million writes) Instant, automatic Unpredictable traffic, new workloads
Provisioned Per RCU/WCU per hour Manual or auto-scaling Predictable traffic, cost optimisation

CRUD Operations

# Put an item
$ aws dynamodb put-item \
    --table-name Deployments \
    --item '{
        "ServiceName": {"S": "api-service"},
        "DeploymentId": {"S": "deploy-2026-001"},
        "Status": {"S": "SUCCESS"},
        "Version": {"S": "v2.1.0"},
        "Timestamp": {"N": "1711800000"}
    }'

# Get an item
$ aws dynamodb get-item \
    --table-name Deployments \
    --key '{"ServiceName": {"S": "api-service"}, "DeploymentId": {"S": "deploy-2026-001"}}' \
    --query 'Item.{Service:ServiceName.S,Status:Status.S,Version:Version.S}'
{
    "Service": "api-service",
    "Status": "SUCCESS",
    "Version": "v2.1.0"
}

# Query all deployments for a service
$ aws dynamodb query \
    --table-name Deployments \
    --key-condition-expression "ServiceName = :svc" \
    --expression-attribute-values '{":svc": {"S": "api-service"}}' \
    --scan-index-forward false \
    --limit 5

DevOps Use Cases

Use Case Table Design
Terraform state locking PK=LockID — prevents concurrent applies
Deployment tracking PK=ServiceName, SK=DeploymentId
Feature flags PK=FlagName, attributes=enabled, percentage
Configuration store PK=Environment, SK=ConfigKey

TTL (Time to Live)

Automatically delete old items:

$ aws dynamodb update-time-to-live \
    --table-name Deployments \
    --time-to-live-specification Enabled=true,AttributeName=ExpiresAt

Set ExpiresAt to a Unix timestamp — DynamoDB deletes the item after that time (within 48 hours).

Common Mistakes

Mistake Why It Hurts Fix
Using Scan instead of Query Reads entire table — slow and expensive Design keys for Query access patterns
Provisioned mode for new workloads Under/over-provisioned, throttling or waste Start with On-Demand, switch later
No TTL on temporary data Table grows forever Enable TTL for logs, sessions, locks
Hot partition (one PK gets all traffic) Throttling on that partition Distribute writes across partition keys

Quick Reference

Task Command
Create table aws dynamodb create-table --table-name NAME --billing-mode PAY_PER_REQUEST ...
Put item aws dynamodb put-item --table-name NAME --item '{...}'
Get item aws dynamodb get-item --table-name NAME --key '{...}'
Query aws dynamodb query --table-name NAME --key-condition-expression "PK = :val"
Delete table aws dynamodb delete-table --table-name NAME

Next → SAM — Serverless Application Model

Updated: