LoginSignup
4
0
お題は不問!Qiita Engineer Festa 2024で記事投稿!
Qiita Engineer Festa20242024年7月17日まで開催中!

DynamoDBを他環境に作るのに手動では耐えられなくなった件

Last updated at Posted at 2024-06-18

はじめに

こんにちは、Gakken LEAP のエンジニアの shogawa です。
今回は、開発環境向けに構築しておいたAWSのDynamoDBを検証環境・本番環境向けに、中身を除いて項目や設定だけをコピーする方法について調べてみたので記事にしてみます。

前提

  • AWSの環境が整っていること
  • AWS CLIが実行できること(実施バージョン:aws-cli/2.13.32)
  • jq がインストールされていること(実施バージョン:version 1.6)
  • DynamoDB に元にするテーブルが作成されていること

また、プロジェクトのAWS環境ではMFA認証しているため、shell でもAWS認証する必要がありますが、その部分については省略します。

ステップの確認

  1. テーブル定義の取得
  2. 設定をjsonに出力(省略できるかも)
  3. コピー先のテーブルを作成
  4. オートスケーリングとターゲットトラッキングポリシーの設定
  5. 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 では教育をアップデートしていきたいエンジニアを絶賛大募集しています!!

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0