DynamoDB Terraform・CDK・CloudFormation ジェネレーター
aws dynamodb describe-table の出力を貼り付けると、テーブルを Terraform、AWS CDK、CloudFormation として取り戻せます。グローバルテーブルのレプリカも含みます。処理はブラウザ内で行われ、貼り付けた内容がどこかに送信されることはありません。
dynamodb-table-iac は、このツールの基盤となるオープンソース(MIT)ライブラリです。
コンソールで作ったテーブルをコードで管理する
多くのテーブルは、コンソールや使い捨てのスクリプトから作られます。対応するリソースを手で書くには、キー、インデックス、キャパシティの設定をひとつずつ describe-table からコピーし、漏れがないことを祈るしかありません。このツールは同じ出力を読み取り、定義を書き出します。
生成されたすべてのファイルには、含まれないものと、既存のテーブルに適用すると変わるものが記載されています。terraform plan より先にトレードオフを確認できます。Terraform ファイルには、既存のテーブルを取り込むためのコメントアウトされた import ブロックも含まれます。
出力先によって違いがあります。Terraform の AWS プロバイダーはベクトルインデックスに対応していないため、ベクトルインデックスはコメントとして定義が残ります。CloudFormation は常に AWS::DynamoDB::GlobalTable を使い、単一リージョンのテーブルはレプリカ 1 つとして表現され、CDK の出力とリソース単位で一致します。
実例: 2 リージョンのテーブル
以下の describe-table の出力は、ソートキー、GSI 1 つ、us-west-2 のレプリカを持つオンデマンドのテーブルのものです。その下の Terraform は、このツールがこの出力から生成するものそのままです。
{
"Table": {
"TableName": "orders",
"TableArn": "arn:aws:dynamodb:us-east-1:123456789012:table/orders",
"TableStatus": "ACTIVE",
"KeySchema": [
{ "AttributeName": "PK", "KeyType": "HASH" },
{ "AttributeName": "SK", "KeyType": "RANGE" }
],
"AttributeDefinitions": [
{ "AttributeName": "PK", "AttributeType": "S" },
{ "AttributeName": "SK", "AttributeType": "S" },
{ "AttributeName": "status", "AttributeType": "S" },
{ "AttributeName": "createdAt", "AttributeType": "N" }
],
"BillingModeSummary": { "BillingMode": "PAY_PER_REQUEST" },
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 0,
"WriteCapacityUnits": 0
},
"GlobalSecondaryIndexes": [
{
"IndexName": "by-status",
"KeySchema": [
{ "AttributeName": "status", "KeyType": "HASH" },
{ "AttributeName": "createdAt", "KeyType": "RANGE" }
],
"Projection": { "ProjectionType": "KEYS_ONLY" },
"IndexStatus": "ACTIVE"
}
],
"StreamSpecification": { "StreamEnabled": true, "StreamViewType": "NEW_AND_OLD_IMAGES" },
"GlobalTableVersion": "2019.11.21",
"Replicas": [{ "RegionName": "us-west-2", "ReplicaStatus": "ACTIVE" }],
"DeletionProtectionEnabled": true
}
}# dynamodb-table-iac: Terraform for DynamoDB table "orders"
# Source: aws dynamodb describe-table, region us-east-1
#
# Not emitted (configure these yourself if the live table uses them):
# - point-in-time recovery (DescribeTable does not return it; a replica declared without it has PITR off)
# - tags (DescribeTable does not return them; applying removes live tags)
# - auto-scaling policies (a fixed capacity snapshot is emitted instead; applying replaces the policy with that snapshot)
# - warm throughput (DescribeTable reports the CURRENT value, which grows with traffic; emitting it would bill a pre-warm)
# - contributor insights, Kinesis streaming destinations and resource policies (DescribeTable does not return them)
# - the KMS key ARN of an SSE-encrypted table (DescribeTable cannot tell an AWS-managed key from a customer-managed one; the AWS-managed key is emitted and the live ARN is left in a comment)
# - settings of non-home replicas that DynamoDB never synchronizes (their deletion protection, PITR and tags are only visible from their own region)
#
# Notes:
# - TTL: not provided — include the output of `aws dynamodb describe-time-to-live` to add it.
#
# To adopt the live table instead of creating a new one, uncomment this import
# block, then run `terraform plan` and check that it reports no changes:
# import {
# to = aws_dynamodb_table.orders
# id = "orders"
# }
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 6.29"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_dynamodb_table" "orders" {
name = "orders"
billing_mode = "PAY_PER_REQUEST"
hash_key = "PK"
range_key = "SK"
stream_enabled = true
stream_view_type = "NEW_AND_OLD_IMAGES"
deletion_protection_enabled = true
attribute {
name = "PK"
type = "S"
}
attribute {
name = "SK"
type = "S"
}
attribute {
name = "status"
type = "S"
}
attribute {
name = "createdAt"
type = "N"
}
global_secondary_index {
name = "by-status"
projection_type = "KEYS_ONLY"
key_schema {
attribute_name = "status"
key_type = "HASH"
}
key_schema {
attribute_name = "createdAt"
key_type = "RANGE"
}
}
# Replica blocks default point_in_time_recovery, deletion_protection_enabled and
# propagate_tags to false: applying this file turns them off on the replicas
# below unless you set them here.
replica {
region_name = "us-west-2"
consistency_mode = "EVENTUAL"
}
}
生成されるコードに含まれるもの
キースキーマとそのキーが参照する属性定義、テーブルと各インデックスの課金モードとキャパシティ、グローバルセカンダリインデックスとローカルセカンダリインデックス、TTL、削除保護、ストリーム、暗号化、テーブルクラス、オンデマンドの最大スループット、出力先が対応している場合のベクトルインデックス、そして整合性モードを含むグローバルテーブルのレプリカ。
含まれないもの
describe-table は、テーブルが持つすべての設定を返すわけではありません。生成されたすべてのファイルのヘッダーに、理由とともに以下が記載されています:
- ポイントインタイムリカバリ(DescribeTable は返しません。これを指定せずに宣言したレプリカでは PITR がオフになります)
- タグ(DescribeTable は返しません。適用すると既存のタグが削除されます)
- Auto Scaling ポリシー(代わりに固定のキャパシティのスナップショットを出力します。適用するとポリシーがそのスナップショットに置き換わります)
- ウォームスループット(DescribeTable はトラフィックに応じて増える現在の値を返します。出力すると事前ウォームアップの料金が発生します)
- CloudWatch Contributor Insights、Kinesis ストリーミング送信先、リソースポリシー(DescribeTable は返しません)
- SSE で暗号化されたテーブルの KMS キー ARN(DescribeTable では AWS マネージドキーとカスタマーマネージドキーを区別できません。AWS マネージドキーを出力し、実際の ARN はコメントに残します)
- DynamoDB が同期しない、ホーム以外のレプリカの設定(削除保護、PITR、タグは、そのレプリカ自身のリージョンからしか確認できません)
よくある質問
テーブル定義はサーバーに送信されますか?
いいえ。コードは貼り付けたテキストからブラウザ内で生成されます。何もアップロードされず、このページが AWS を呼び出すこともありません。
TTL を含めるには?
TTL は describe-table の出力には含まれません。テーブルに対して aws dynamodb describe-time-to-live を実行し、その TimeToLiveDescription オブジェクトを同じ JSON 内の Table の隣に貼り付けてください。含めない場合、生成されたファイルには TTL が指定されていない旨が記載されます。
生成されたコードはどのリージョンを対象にしますか?
TableArn から読み取ったテーブルのホームリージョンです。DescribeTable はそれ以外のリージョンをすべてレプリカとして返すため、テーブルを管理しているリージョンで実行してください。DynamoDB Local から取得した出力には実際のリージョンがないため、リージョンはご自身で設定してください。
既存のテーブルに適用できますか?
はい、ヘッダーを読んだうえで適用してください。Terraform ファイルにはコメントアウトされた import ブロックが含まれています。コメントを外して terraform plan を実行してください。plan が示す変更は、ヘッダーに記載されたもの(既存のタグの削除など)だけのはずです。報告された変更をそのリストと照らし合わせて確認してください。