はじめに
こんにちは、Gakken LEAP のエンジニアの shogawa です。
今回は、開発環境向けに構築しておいたAWSのDynamoDBを検証環境・本番環境向けに、中身を除いて項目や設定だけをコピーする方法について調べてみたので記事にしてみます。
前提
- AWSの環境が整っていること
- AWS CLIが実行できること(実施バージョン:aws-cli/2.13.32)
- jq がインストールされていること(実施バージョン:version 1.6)
- DynamoDB に元にするテーブルが作成されていること
また、プロジェクトのAWS環境ではMFA認証しているため、shell でもAWS認証する必要がありますが、その部分については省略します。
ステップの確認
- テーブル定義の取得
- 設定をjsonに出力(省略できるかも)
- コピー先のテーブルを作成
- オートスケーリングとターゲットトラッキングポリシーの設定
- 1つのshellとして作成
テーブル定義の取得
まず、コピー元のテーブル定義を aws コマンドにて取得します。
aws dynamodb describe-table --table-name "origin_table_name"
設定をjsonに出力
この後のコピー先のテーブルを作成するのに、データの削除や設定のコピーのためのjsonファイルに出力をしておきます。
このあたりはバージョン等によって要否がわかれることがあるので、公式ドキュメントを参考に必要な設定を出力してください。
jq '.Table' |
jq 'del(.ProvisionedThroughput.NumberOfDecreasesToday)' |
jq 'del(.ProvisionedThroughput.LastIncreaseDateTime)' |
jq 'del(.ProvisionedThroughput.LastDecreaseDateTime)' |
jq 'del(.TableSizeBytes)' |
jq 'del(.TableStatus)' |
jq 'del(.ItemCount)' |
jq 'del(.CreationDateTime)' |
jq 'del(.TableArn)' |
jq 'del(.TableId)' |
jq 'del(.LatestStreamLabel)' |
jq 'del(.LatestStreamArn)' |
jq 'del(.StreamSpecification.StreamEnabled)' |
jq 'del(.StreamSpecification.StreamViewType)' |
jq 'del(.RestoreSummary.RestoreDateTime)' |
jq 'del(.RestoreSummary.RestoreInProgress)' |
jq 'del(.RestoreSummary.SourceBackupArn)' |
jq 'del(.RestoreSummary.SourceTableArn)' |
jq 'del(.SSEDescription.Status)' |
jq 'del(.SSEDescription.SSEType)' |
jq 'del(.SSEDescription.KMSMasterKeyArn)' |
jq 'del(.SSEDescription.InaccessibleEncryptionDateTime)' |
jq 'del(.SSEDescription.Error)' |
jq 'del(.TableClassSummary)' |
# テーブル名を変換して出力
jq --arg table "copy_table_name" '.TableName = "origin_table_name"'
また、グローバルセカンダリインデックスやローカルセカンダリインデックスがある場合も、設定をjsonに出力しておきます。
# グローバルセカンダリインデックス
jq 'del(.GlobalSecondaryIndexes[].IndexArn)' |
jq 'del(.GlobalSecondaryIndexes[].ItemCount)' |
jq 'del(.GlobalSecondaryIndexes[].IndexStatus)' |
jq 'del(.GlobalSecondaryIndexes[].IndexSizeBytes)' |
jq 'del(.GlobalSecondaryIndexes[].ProvisionedThroughput.NumberOfDecreasesToday)' |
jq 'del(.GlobalSecondaryIndexes[].ProvisionedThroughput.LastIncreaseDateTime)' |
jq 'del(.GlobalSecondaryIndexes[].ProvisionedThroughput.LastDecreaseDateTime)'
# ローカルセカンダリインデックス
jq 'del(.LocalSecondaryIndexes[].IndexArn)' |
jq 'del(.LocalSecondaryIndexes[].ItemCount)' |
jq 'del(.LocalSecondaryIndexes[].IndexStatus)' |
jq 'del(.LocalSecondaryIndexes[].IndexSizeBytes)' |
jq 'del(.LocalSecondaryIndexes[].ProvisionedThroughput.NumberOfDecreasesToday)' |
jq 'del(.LocalSecondaryIndexes[].ProvisionedThroughput.LastIncreaseDateTime)' |
jq 'del(.LocalSecondaryIndexes[].ProvisionedThroughput.LastDecreaseDateTime)'
コピー先のテーブルを作成
続いて、出力したjsonファイルを元にテーブルを作成します。
aws dynamodb create-table --cli-input-json "file://copy_table_name.json"
オートスケーリングとターゲットトラッキングポリシーの設定
これまでの設定ではコピーされない、オートスケーリングとターゲットラッキングポリシーの設定をしていきます。
# オートスケーリングの設定
aws application-autoscaling register-scalable-target \
--service-namespace dynamodb \
--resource-id table/copy_table_name \
--scalable-dimension dynamodb:table:ReadCapacityUnits \
--min-capacity 1 \
--max-capacity 10
# オートスケーリングの設定
aws application-autoscaling register-scalable-target \
--service-namespace dynamodb \
--resource-id table/copy_table_name \
--scalable-dimension dynamodb:table:WriteCapacityUnits \
--min-capacity 1 \
--max-capacity 10
# ターゲットトラッキングポリシー(ReadCapacity)の設定
aws application-autoscaling put-scaling-policy \
--service-namespace dynamodb \
--resource-id table/copy_table_name \
--scalable-dimension dynamodb:table:ReadCapacityUnits \
--policy-name ReadCapacityScalingPolicy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration file://read-target-tracking-policy.json
# ターゲットトラッキングポリシー(WriteCapacity)の設定
aws application-autoscaling put-scaling-policy \
--service-namespace dynamodb \
--resource-id table/copy_table_name \
--scalable-dimension dynamodb:table:WriteCapacityUnits \
--policy-name WriteCapacityScalingPolicy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration file://write-target-tracking-policy.json
1つの shell として作成
各コマンドを実行すればDynamoDBのテーブルコピーができていると思います。
複数環境にたいしてコピーがやりやすいよう、1つのshellとしてまとめていきます。
コピー元、コピー先のファイル名はshellのパラメータにして各コマンドを整えていきます。
# 実行コマンド
./copyDynamoDB.sh origin-table-name copy-table-name
以下、shellの全容です。
# テーブル名は引数にて指定
ORG_TABLE_NAME=$1
COPY_TABLE_NAME=$2
# もとテーブルの定義を取得
DESCRIPTION=$(aws dynamodb describe-table --table-name $ORG_TABLE_NAME)
# 不要な項目の削除
CONTENTS=`echo $DESCRIPTION |
jq '.Table' |
jq 'del(.ProvisionedThroughput.NumberOfDecreasesToday)' |
jq 'del(.ProvisionedThroughput.LastIncreaseDateTime)' |
jq 'del(.ProvisionedThroughput.LastDecreaseDateTime)' |
jq 'del(.TableSizeBytes)' |
jq 'del(.TableStatus)' |
jq 'del(.ItemCount)' |
jq 'del(.CreationDateTime)' |
jq 'del(.TableArn)' |
jq 'del(.TableId)' |
jq 'del(.LatestStreamLabel)' |
jq 'del(.LatestStreamArn)' |
jq 'del(.StreamSpecification.StreamEnabled)' |
jq 'del(.StreamSpecification.StreamViewType)' |
jq 'del(.RestoreSummary.RestoreDateTime)' |
jq 'del(.RestoreSummary.RestoreInProgress)' |
jq 'del(.RestoreSummary.SourceBackupArn)' |
jq 'del(.RestoreSummary.SourceTableArn)' |
jq 'del(.SSEDescription.Status)' |
jq 'del(.SSEDescription.SSEType)' |
jq 'del(.SSEDescription.KMSMasterKeyArn)' |
jq 'del(.SSEDescription.InaccessibleEncryptionDateTime)' |
jq 'del(.SSEDescription.Error)' |
jq 'del(.TableClassSummary)' |
# テーブル名を変換して出力
jq --arg table "$COPY_TABLE_NAME" '.TableName = $table'
`
# グローバルセカンダリインデックスがある場合
if test `echo $CONTENTS | jq 'has("GlobalSecondaryIndexes")'` = true; then
echo has GlobalSecondaryIndexes
CONTENTS=`echo $CONTENTS |
jq 'del(.GlobalSecondaryIndexes[].IndexArn)' |
jq 'del(.GlobalSecondaryIndexes[].ItemCount)' |
jq 'del(.GlobalSecondaryIndexes[].IndexStatus)' |
jq 'del(.GlobalSecondaryIndexes[].IndexSizeBytes)' |
jq 'del(.GlobalSecondaryIndexes[].ProvisionedThroughput.NumberOfDecreasesToday)' |
jq 'del(.GlobalSecondaryIndexes[].ProvisionedThroughput.LastIncreaseDateTime)' |
jq 'del(.GlobalSecondaryIndexes[].ProvisionedThroughput.LastDecreaseDateTime)'
`
# ローカルセカンダリインデックスがある場合
elif test `echo $CONTENTS | jq 'has("LocalSecondaryIndexes")'` = true; then
echo has LocalSecondaryIndexes
CONTENTS=`echo $CONTENTS |
jq 'del(.LocalSecondaryIndexes[].IndexArn)' |
jq 'del(.LocalSecondaryIndexes[].ItemCount)' |
jq 'del(.LocalSecondaryIndexes[].IndexStatus)' |
jq 'del(.LocalSecondaryIndexes[].IndexSizeBytes)' |
jq 'del(.LocalSecondaryIndexes[].ProvisionedThroughput.NumberOfDecreasesToday)' |
jq 'del(.LocalSecondaryIndexes[].ProvisionedThroughput.LastIncreaseDateTime)' |
jq 'del(.LocalSecondaryIndexes[].ProvisionedThroughput.LastDecreaseDateTime)'
`
fi
# jsonファイルに出力
echo $CONTENTS > $COPY_TABLE_NAME.json
# コピーテーブルを作成
aws dynamodb create-table --cli-input-json "file://"$COPY_TABLE_NAME".json"
# オートスケーリングの設定
aws application-autoscaling register-scalable-target \
--service-namespace dynamodb \
--resource-id table/$COPY_TABLE_NAME \
--scalable-dimension dynamodb:table:ReadCapacityUnits \
--min-capacity 1 \
--max-capacity 10
# オートスケーリングの設定
aws application-autoscaling register-scalable-target \
--service-namespace dynamodb \
--resource-id table/$COPY_TABLE_NAME \
--scalable-dimension dynamodb:table:WriteCapacityUnits \
--min-capacity 1 \
--max-capacity 10
# ターゲットトラッキングポリシー(ReadCapacity)の設定
aws application-autoscaling put-scaling-policy \
--service-namespace dynamodb \
--resource-id table/$COPY_TABLE_NAME \
--scalable-dimension dynamodb:table:ReadCapacityUnits \
--policy-name ReadCapacityScalingPolicy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration file://read-target-tracking-policy.json
# ターゲットトラッキングポリシーの(WriteCapacity)の設定
aws application-autoscaling put-scaling-policy \
--service-namespace dynamodb \
--resource-id table/$COPY_TABLE_NAME \
--scalable-dimension dynamodb:table:WriteCapacityUnits \
--policy-name WriteCapacityScalingPolicy \
--policy-type TargetTrackingScaling \
--target-tracking-scaling-policy-configuration file://write-target-tracking-policy.json
まとめ
今回は、大きめのプロジェクトでDynamoDBを使うことになり、開発環境で作ったものの検証環境、本番環境に向けて構築をどうしようかと思い、shell一発でテーブルのコピーができるようにしてみました。
参考になれば幸いです。
Gakken LEAP では教育をアップデートしていきたいエンジニアを絶賛大募集しています!!