DataPipelineを使ってDynamoDBのデータを別のAWSアカウントに移行してみた

既存のDynamoDBから別アカウントのDynamoDB内へデータ移行する
2021.07.20

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

オペレーション部 加藤(早)です。

今日は異なるAWSアカウントのDynamoDBへのデータ移行をやってみます。

以下の公式ドキュメントを参考に、DataPipelineを初めて触る方向けに少し解説を入れながら進めます。 DataPipelineを使ったことのある方は公式ドキュメントで十分かと思います。

Data Pipeline を使用して DynamoDB テーブルを別のアカウント内の S3 にバックアップする

ターゲットアカウントへS3, DynamoDBテーブルの作成

移行先アカウントに、必要なリソースを作成しておきます。

  • S3
  • DynamoDBテーブル

今回はすべて東京リージョンに作成しました。

この段階ではS3はすべてデフォルト設定でOKです(あとのステップでバケットポリシーの設定を追加します)。
Dynamoはプライマリパーティションキー、ソートキーの設定を揃えて作成しました。

IAMロールの作成

両アカウントともに、Data Pipeline用のIAMロール「DataPipelineDefaultRole」および「DataPipelineDefaultResourceRole」が必要です。
Data Pipelineを利用したことがない場合、手動で作成しておきます。

IAMロール作成画面からそれぞれのユースケースを選択し、
すべてデフォルト設定を選択していくと作成できます。(ロール名は手入力が必要)

 出来上がったロールはこのようになります。

加えて、ソース側のロールにのみ、ターゲットアカウントのS3へのアクセス許可を設定しておきます。

追加したポリシーは以下のとおりです。
サンプルですので、コピペされる場合は kato-example-bucket → 予め作成したバケット名へ差し替えしてください。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": [
                "s3:AbortMultipartUpload",
                "s3:GetBucketLocation",
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::kato-example-bucket/*",
                "arn:aws:s3:::kato-example-bucket"     
            ]
        }
    ]
}

バケットポリシーの設定

Export DynamoDB table to S3 Data Pipeline テンプレートを使用してパイプラインを作成します。 ターゲットアカウントのバケットに、ソースからのアクセス許可設定を入れます。

以下のポリシーはサンプルですので、コピペされる場合は2点差し替えが必要です。

  • 111122223333 → ソースアカウントのAWS IDへ変更
  • kato-example-bucket → 予め作成したバケット名へ変更
{
    "Version": "2012-10-17",
    "Id": "",
    "Statement": [
        {
            "Sid": "",
            "Effect": "Allow",
            "Action": "s3:*",
            "Principal": {
                "AWS": [
                    "arn:aws:iam::111122223333:role/DataPipelineDefaultRole",
                    "arn:aws:iam::111122223333:role/DataPipelineDefaultResourceRole"
                ]
            },
            "Resource": [
                "arn:aws:s3:::kato-example-bucket",
                "arn:aws:s3:::kato-example-bucket/*"
            ]
        }
    ]
}

Data Pipelineの作成・実行(エクスポート)

ソースアカウント側で、 Export DynamoDB table to S3 Data Pipeline テンプレートを使用してパイプラインを作成します。

  • Parameters記載する項目
    • DynamoDBのテーブル名
    • 出力先S3バケット名 ※ s3://バケット名/ の形。フォルダ指定も可能
    • DynamoDBスループット(消費するキャパシティ) ※ 今回はデフォルト値
    • DynamoDBのリージョン
  • Schedule
    • 一度きりの実行なので、on pipeline activation を選択
  • Pipeline Configuration
    • ログ出力先
  • Security/Access
    • Default

パイプラインをアクティブ化する前に、[Edit in Architect] を選択します。

別リージョンのS3に出力するため、諸々に必要なアクセス許可を与えます。
ドキュメントに従い、EmrActivityオブジェクトをクリックし、"Step:" のテキストボックスを以下の内容で上書きします。

s3://dynamodb-dpl-#{myDDBRegion}/emr-ddb-storage-handler/4.11.0/emr-dynamodb-tools-4.11.0-SNAPSHOT-jar-with-dependencies.jar,org.apache.hadoop.dynamodb.tools.DynamoDBExport,-Dfs.s3.canned.acl=BucketOwnerFullControl,#{output.directoryPath},#{input.tableName},#{input.readThroughputPercent}

また、画面左下にオレンジ色でバリデーションのワーニングが出ているのを見つけました。素直に修正しておきます。
(実行時間制限を入れておいたほうが良いよ、という推奨項目でしたので、 項目数11,263 のテーブルに対して雑に2時間で設定しておきました)

[Save] を選択してから [Activate] をクリックしてパイプラインをアクティブ化し、ジョブが動くのを見守ります。

11,263 レコードありましたが、10分程度でジョブが完了しました。

S3にもアップロードされています。
(2回目の実行あとにスクショを撮ったので2つありますが、実行日時が確認できます)

Data Pipelineの作成・実行(インポート)

今度はターゲットアカウント側でインポートをします。

Import DynamoDB backup data from S3 Data Pipeline テンプレートを使用してパイプラインを作成します。
パラメータはほぼ同じですが、S3バケット名だけではなく、先程のexportで出力されたパスを記載する必要がある点注意です。

今回は同じアカウント内の作業になるので、アクセス許可の上書きは必要ありません。
ただ、export時と同じく実行時間制限の入力を推奨するWarningが出るので、その点のみ追加で設定してからジョブを実行しました。

実行から3時間ほど経過して(exportよりimportのほうが時間がかかる様子)、移行が完了しました。

DynamoDBの項目数は、移行元テーブルの項目数と一致していました。

まとめ

Data Pipelineって、裏側にEMRがいるんでしょ?触ったことないよ…とハードルを高く感じていましたが、触ってみるとそんなことはなかったです。
DynamoDBのデータ移行をシンプルに済ませるために是非お試ししてみてはいかがでしょうか。