📦

localstackとterraformでローカル環境のdynamodb作ってみた

に公開

はじめに

あるデータをdynamodbに保存する機能を開発することになったのですが、AWSをそのまま利用すると課金が発生します。
なのでlocalstackという、ローカルでAWS環境を再現できるエミュレータを使用することにしました。
備忘録としてdynamodbを構築するまでをまとめました。

localstackのインストール

インストールはこちら
いろいろ方法が紹介されていますが、私はdocker composeの方法を採用しました。
https://docs.localstack.cloud/aws/getting-started/installation/#docker-compose

今回は無料の範囲でなんとかなっているのですが、例えばデータの永続化であるとかその他リソースを構築したい場合は有料プランに加入する必要があるそうです。

疎通確認

localstackのdocker環境を立ち上げた後、curlで疎通確認します。
こんな感じでjsonが出力されたらokです。

 curl localhost:4566/_localstack/health

# 出力結果
{"services": {"acm": "available", "apigateway": "available", "cloudformation": "available", "cloudwatch": "available", "config": "available", "dynamodb": "running", "dynamodbstreams": "available", "ec2": "available", "es": "available", "events": "available", "firehose": "available", "iam": "available", "kinesis": "available", "kms": "available", "lambda": "available", "logs": "available", "opensearch": "available", "redshift": "available", "resource-groups": "available", "resourcegroupstaggingapi": "available", "route53": "available", "route53resolver": "available", "s3": "running", "s3control": "available", "scheduler": "available", "secretsmanager": "available", "ses": "available", "sns": "available", "sqs": "available", "ssm": "available", "stepfunctions": "available", "sts": "available", "support": "available", "swf": "available", "transcribe": "available"}, "edition": "community", "version": "4.9.3.dev51"}

dynamodbを構築する

terraformを使ってdynamodbを構築します。
localstackのdocker環境とは別のディレクトリでterraformを作成しました。
terraformのコードの大枠はgeminiに出力してもらいました。

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

provider "aws" {
  region = "ap-northeast-1"

  access_key = "test"
  secret_key = "test"

  skip_credentials_validation = true
  skip_metadata_api_check     = true
  skip_requesting_account_id  = true

  endpoints {
    dynamodb = "http://localhost:4566"
    s3       = "http://localhost:4566"
  }
}

resource "aws_dynamodb_table" "dynamodb-test-table" {
  name           = "dynamodb-test-table"
  billing_mode   = "PAY_PER_REQUEST"
  hash_key       = "TenantId"
  range_key      = "CreatedAt"

  attribute {
    name = "TenantId"
    type = "S"
  }

  attribute {
    name = "CreatedAt"
    type = "S"
  }

  ttl {
    attribute_name = "ExpiredAt"
    enabled = true
  }

  tags = {
    Environment = "local-dev"
    ManagedBy   = "Terraform"
  }
}

tfファイルが作成できたら、terraformコマンドを実行してlocalstackに反映します。

# terraformの初期化
 terraform init

# terraformの実行計画確認
 terraform plan

# localstackに反映
 terraform apply

dynamodbが反映されているか確認

# 以下のような感じにcredentialsを設定
 cat ~/.aws/credentials
[localstack]
aws_access_key_id = test
aws_secret_access_key = test

ターミナルからawsコマンドでdynamodbの情報を出力

 aws dynamodb describe-table --table-name dynamodb-test-table \
 --endpoint-url=http://localhost:4566 \
 --profile=localstack \
 --region=ap-northeast-1

 # 出力結果
{
    "Table": {
        "AttributeDefinitions": [
            {
                "AttributeName": "CreatedAt",
                "AttributeType": "S"
            },
            {
                "AttributeName": "TenantId",
                "AttributeType": "S"
            }
        ],
        "TableName": "dynamodb-test-table",
        "KeySchema": [
            {
                "AttributeName": "TenantId",
                "KeyType": "HASH"
            },
            {
                "AttributeName": "CreatedAt",
                "KeyType": "RANGE"
            }
        ],
        "TableStatus": "ACTIVE",
        "CreationDateTime": "2025-10-30T14:24:39.366000+09:00",
        "ProvisionedThroughput": {
            "LastIncreaseDateTime": "1970-01-01T09:00:00+09:00",
            "LastDecreaseDateTime": "1970-01-01T09:00:00+09:00",
            "NumberOfDecreasesToday": 0,
            "ReadCapacityUnits": 0,
            "WriteCapacityUnits": 0
        },
        "TableSizeBytes": 0,
        "ItemCount": 0,
        "TableArn": "arn:aws:dynamodb:ap-northeast-1:000000000000:table/dynamodb-test-table",
        "TableId": "cfaafca0-d042-47fb-ba72-a6bc79b74353",
        "BillingModeSummary": {
            "BillingMode": "PAY_PER_REQUEST",
            "LastUpdateToPayPerRequestDateTime": "2025-10-30T14:24:39.366000+09:00"
        },
        "DeletionProtectionEnabled": false,
        "WarmThroughput": {
            "ReadUnitsPerSecond": 12000,
            "WriteUnitsPerSecond": 4000,
            "Status": "ACTIVE"
        }
    }
}

さいごに

とてもサクッと環境が構築できたので助かりました。
これでローカル環境の機能実装も捗ります。

Discussion