

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# カスタム実装を使用してアカウント間で Amazon DynamoDB テーブルをコピー
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation"></a>

*Ramkumar Ramanujam (Amazon Web Services)*

## 概要
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-summary"></a>

Amazon Web Services (AWS) で Amazon DynamoDB を使用する場合、通常のユースケースは、開発、テスト、またはステージング環境の DynamoDB テーブルを本番環境のテーブルデータにコピーまたは同期することです。標準的な方法として、環境ごとに異なる AWS アカウントを使用します。

DynamoDB が AWS Backup を使用したクロスアカウントバックアップに適用されます。AWS Backup を使用する際に関連するストレージコストについては、[AWS Backup 料金表](https://aws.amazon.com/backup/pricing/)を参照してください。AWS Backup を使用してアカウントをコピーする場合、ソースアカウントとターゲットアカウントは AWS Organizations 組織の一部である必要があります。AWS Glue などの AWS サービスを使用してクロスアカウントのバックアップと復元を行うソリューションは他にもあります。ただし、これらのソリューションを使用すると、デプロイして管理する AWS サービスの数が増えるため、アプリケーションのフットプリントが増加します。 

Amazon DynamoDB Streamsを使用して、ソースアカウントのテーブルの変更をキャプチャすることもできます。次に、AWS Lambda 関数を開始し、ターゲットアカウントのターゲットテーブルに対応する変更を加えることができます。ただし、このソリューションは、ソーステーブルとターゲットテーブルを常に同期させる必要があるユースケースにも当てはまります。データが頻繁に更新される開発、テスト、ステージング環境には適用されない場合があります。

このパターンでは、Amazon DynamoDB テーブルをあるアカウントから別のアカウントにコピーするカスタムソリューションを実装する手順を示します。このパターンでは、C\$1、Java、Python などの一般的なプログラミング言語を使用して実装できます。[AWS SDK](https://aws.amazon.com/tools/) に適用されている言語を使用することを推薦します。

## 前提条件と制限事項
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-prereqs"></a>

**前提条件**
+ アクティブなAWS アカウント
+ 両方のアカウントの DynamoDB テーブル
+ AWS Identity and Access Management (IAM) ロールとポリシー
+ C\$1、Java、Python などの一般的なプログラミング言語を使用して Amazon DynamoDB テーブルにアクセスする方法に関する知識

**制限事項**

このパターンでは、約 2 GB 以下の DynamoDB テーブルに適用されます。接続やセッションの中断、調整、障害や再試行を処理するロジックを追加すれば、サイズの大きいテーブルにも使用できます。

ソーステーブルから項目を読み取る DynamoDB スキャンオペレーションは、1 回の呼び出しで最大 1 MB のデータしか取得できません。2 GB を超える大きなテーブルでは、この制限によりテーブル全体のコピーを実行する合計時間が長くなる可能性があります。

## アーキテクチャ
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-architecture"></a>

次の図は、ソースとターゲットの AWS アカウント間のカスタム実装を示しています。IAM ポリシーとセキュリティトークンは、カスタム実装で使用されます。データはソースアカウントの Amazon DynamoDB から読み取られ、ターゲットアカウントの DynamoDB に書き込まれます。

![\[カスタム実装を使用してコピーするためのソースおよびターゲットアカウントのアーキテクチャ。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/ba8175be-9809-4c2e-b2d1-6b9180ed056c/images/d9d4c2c8-ff04-443f-9137-e37b8e23ccb5.png)


 

**自動化とスケール**

このパターンでは、サイズが約 2 GB と小さい DynamoDB テーブルに適用されます。 

このパターンを大きなテーブルに適用するには、以下の問題に対処します。
+ テーブルコピー操作中は、異なるセキュリティトークンを使用して 2 つのアクティブセッションが維持されます。テーブルコピー操作にトークンの有効期限よりも時間がかかる場合は、セキュリティトークンを更新するロジックを設定する必要があります。 
+ 十分な読み込みキャパシティーユニット (WCU) と書き込みキャパシティーユニット (WCU) がプロビジョニングされていない場合、ソーステーブルまたはターゲットテーブルの読み込みまたは書き込みが制限される可能性があります。これらの例外を必ずキャッチして処理します。 
+ その他の障害や例外を処理し、再試行メカニズムを導入して、コピー操作が失敗したところから再試行または続行できるようにします。

## ツール
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-tools"></a>

**ツール**
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) – Amazon DynamoDB は、フルマネージド NoSQL データベースサービスであり、シームレスなスケーラビリティを備えた高速で予測可能なパフォーマンスを提供します。 
+ 必要な追加ツールは、実装に選択したプログラミング言語によって異なります。たとえば、C\$1 を使用する場合、Microsoft Visual Studio と次の NuGet パッケージが必要になります。
  + `AWSSDK`
  + `AWSSDK.DynamoDBv2`

**コード**

次の Python コードスニペットは、Boto3 ライブラリを使用して DynamoDB テーブルを削除して再作成します。

IAM ユーザーの `AWS_ACCESS_KEY_ID` と `AWS_SECRET_ACCESS_KEY` は長期的な認証情報であるため、使用しません。プログラムで AWS のサービスにアクセスする場合は使用しません。一時的な認証情報についての詳細は、「*IAM ユーザーガイド*」を参照してください。

次のコードスニペットで使用されている `AWS_ACCESS_KEY_ID`、`AWS_SECRET_ACCESS_KEY` 、および `TEMPORARY_SESSION_TOKEN` は AWS Security Token Service (AWS STS) から取得された一時的な認証情報です。

```
import boto3
import sys
import json

#args = input-parameters = GLOBAL_SEC_INDEXES_JSON_COLLECTION, ATTRIBUTES_JSON_COLLECTION, TARGET_DYNAMODB_NAME, TARGET_REGION, ...

#Input param: GLOBAL_SEC_INDEXES_JSON_COLLECTION
#[{"IndexName":"Test-index","KeySchema":[{"AttributeName":"AppId","KeyType":"HASH"},{"AttributeName":"AppType","KeyType":"RANGE"}],"Projection":{"ProjectionType":"INCLUDE","NonKeyAttributes":["PK","SK","OwnerName","AppVersion"]}}]

#Input param: ATTRIBUTES_JSON_COLLECTION
#[{"AttributeName":"PK","AttributeType":"S"},{"AttributeName":"SK","AttributeType":"S"},{"AttributeName":"AppId","AttributeType":"S"},{"AttributeName":"AppType","AttributeType":"N"}]

region = args['TARGET_REGION']
target_ddb_name = args['TARGET_DYNAMODB_NAME']

global_secondary_indexes = json.loads(args['GLOBAL_SEC_INDEXES_JSON_COLLECTION'])
attribute_definitions = json.loads(args['ATTRIBUTES_JSON_COLLECTION'])

# Drop and create target DynamoDB table
dynamodb_client = boto3.Session(
        aws_access_key_id=args['AWS_ACCESS_KEY_ID'],
        aws_secret_access_key=args['AWS_SECRET_ACCESS_KEY'],
        aws_session_token=args['TEMPORARY_SESSION_TOKEN'],
    ).client('dynamodb')
    
# Delete table
print('Deleting table: ' + target_ddb_name + ' ...')

try:
    dynamodb_client.delete_table(TableName=target_ddb_name)

    #Wait for table deletion to complete
    waiter = dynamodb_client.get_waiter('table_not_exists')
    waiter.wait(TableName=target_ddb_name)
    print('Table deleted.')
except dynamodb_client.exceptions.ResourceNotFoundException:
    print('Table already deleted / does not exist.')
    pass

print('Creating table: ' + target_ddb_name + ' ...')

table = dynamodb_client.create_table(
    TableName=target_ddb_name,
    KeySchema=[
        {
            'AttributeName': 'PK',
            'KeyType': 'HASH'  # Partition key
        },
        {
            'AttributeName': 'SK',
            'KeyType': 'RANGE'  # Sort key
        }
    ],
    AttributeDefinitions=attribute_definitions,
    GlobalSecondaryIndexes=global_secondary_indexes,
    BillingMode='PAY_PER_REQUEST'
)
    
waiter = dynamodb_client.get_waiter('table_exists')
waiter.wait(TableName=target_ddb_name)
    
print('Table created.')
```

## ベストプラクティス
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-best-practices"></a>

**一時認証情報**

セキュリティのベストプラクティスとして、プログラムで AWS サービスにアクセスするときは、IAM ユーザーの `AWS_ACCESS_KEY_ID` と `AWS_SECRET_ACCESS_KEY` を使用することは避けてください。これらは長期的な認証情報であるためです。AWS サービスにプログラムからアクセスするには、常に一時的な認証情報を使用します。

例として、開発者は開発中にアプリケーションの IAM ユーザーの `AWS_ACCESS_KEY_ID` と `AWS_SECRET_ACCESS_KEY` をハードコーディングしますが、変更をコードリポジトリにプッシュする前にハードコードされた値の削除に失敗します。これらの公開された認証情報は、意図しないユーザーや悪意のあるユーザーによって使用される可能性があり、深刻な問題を引き起こす可能性があります (特に公開された認証情報に管理者権限がある場合)。これらの公開後、これらの認証情報を IAM コンソールまたは AWS コマンドラインインターフェイス (AWS CLI) を使用して、直ちに無効化または削除する必要があります。

AWS サービスにプログラムでアクセスするための一時的な認証情報を取得するには、AWS STS を使用します。一時的な認証情報は、指定された時間 (15 分から 36 時間まで) のみ有効です。一時的な認証情報の最大許容期間は、ロール設定やロールチェーンなどの要因によって異なります。AWS STS の詳細については、[ドキュメント](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html)を参照してください。

## エピック
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-epics"></a>

### DynamoDB テーブルのセットアップ
<a name="set-up-dynamodb-tables"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| DynamoDB テーブルを作成します。 | ソースとターゲットの両方の AWS アカウントで、インデックスを使用して DynamoDB テーブルを作成します。キャパシティプロビジョニングをオンデマンドモードに設定します。これにより、DynamoDB はワークロードに基づいて読み取り/書き込みキャパシティーを動的にスケーリングできます。 あるいは、4000 の RCU と 4000 WCU のプロビジョニングされたキャパシティを使用することもできます。 | アプリ開発者、DBA、移行エンジニア | 
| ソーステーブルにデータを入力します。 | ソースアカウントの DynamoDB テーブルにテストデータを入力します。テストデータが 50 MB 以上あると、テーブルコピー中に消費される RCU の最大値と平均値を確認するのに役立ちます。その後、必要に応じてキャパシティプロビジョニングを変更できます。 | アプリ開発者、DBA、移行エンジニア | 

### DynamoDB テーブルにアクセスするための認証情報をセットアップ
<a name="set-up-credentials-to-access-the-dynamodb-tables"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| ソースとターゲットの DynamoDB テーブルにアクセスするための IAM ロールを作成します。 | ソースアカウントの DynamoDB テーブルにアクセス (読み取り) する権限を持つ IAM ロールをソースアカウントで作成します。ソースアカウントをこのロールの信頼できるエンティティとして追加します。ターゲットアカウントの DynamoDB テーブルへのアクセス (作成、読み取り、更新、削除) 権限を持つ IAM ロールをターゲットアカウントで作成します。 ターゲットアカウントをこのロールの信頼できるエンティティとして追加します。 | アプリ開発者、AWS DevOps | 

### アカウントから別のアカウントにテーブルデータをコピー
<a name="copy-table-data-from-one-account-to-another"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| IAM ロールの一時認証情報を取得します。 | ソースアカウントで作成した IAM ロールの一時認証情報を取得します。ターゲットアカウントで作成された IAM ロールの一時認証情報を取得します。IAM ロールの一時認証情報を取得する 1 つの方法は、AWS CLI から AWS STS を使用します。<pre>aws sts assume-role --role-arn arn:aws:iam::<account-id>:role/<role-name> --role-session-name <session-name> --profile <profile-name></pre>適切な AWS プロファイル (ソースアカウントまたはターゲットアカウントに対応) を使用します。一時的なセキュリティ認証情報の使用方法の詳細については、以下を参照してください。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation.html) | アプリ開発者、移行エンジニア | 
| ソースとターゲットの DynamoDB アクセス用に DynamoDB クライアントを初期化します。 | AWS SDK によって提供される DynamoDB クライアントを、ソースとターゲットの DynamoDB テーブル用に初期化します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation.html)IAM の一時認証情報を使用してリクエストを行う方法についての詳細は、[AWS ドキュメント](https://docs.aws.amazon.com/AmazonS3/latest/userguide/AuthUsingTempSessionToken.html) を参照してください。 | アプリ開発者 | 
| ターゲットテーブルをドロップして再作成。 | ターゲットアカウントの DynamoDB クライアントを使用して、ターゲットアカウントのターゲット DynamoDB テーブル (およびインデックス) を削除して再作成します。DynamoDB テーブルからすべてのレコードを削除すると、プロビジョニングされた WCU が消費されるため、コストのかかる操作です。テーブルを削除して再作成することで、このような追加コストを回避できます。テーブルを作成した後でもインデックスを追加できますが、これには 2 ～ 5 分ほど時間がかかります。テーブルの作成中に インデックスコレクションを `createTable` 呼び出しに渡すことで、インデックスを作成することがより効率的になります。 | アプリ開発者 | 
| テーブルコピーを実行します。 | すべてのデータがコピーされるまで、次の手順を繰り返します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation.html)詳細については、「*添付ファイル*」セクションで、C\$1 のリファレンス実装 (テーブルの削除、作成、入力用) を参照してください。テーブル設定の JavaScript オブジェクト表記 (JSON) ファイルの例も添付されています。 | アプリ開発者 | 

## 関連リソース
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-resources"></a>
+ [Amazon DynamoDB ドキュメント](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html)
+ [AWS アカウント内での IAM ユーザーの作成](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html)
+ [AWS SDK](https://aws.amazon.com/tools/)
+ [AWS リソースを使用した一時的な認証情報の使用](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_temp_use-resources.html)

## 追加情報
<a name="copy-amazon-dynamodb-tables-across-accounts-using-a-custom-implementation-additional"></a>

このパターンでは、C\$1 を使用して 200,000 項目 (平均項目サイズは 5 KB、テーブルサイズは 250 MB) の DynamoDB テーブルをコピーするために実装されました。ターゲット DynamoDB テーブルは、4000 RCU と 4000 WCU のキャパシティーをプロビジョニングして設定されました。

テーブルの削除と再作成を含むテーブルコピー操作 (ソースアカウントからターゲットアカウントへ) には 5 分かかりました。消費されたキャパシティユニットの総容量：30,000 RCU と約 400,000 WCU。

DynamoDB キャパシティモードの詳細については、AWS ドキュメントの[読み取り/書き込みキャパシティモード](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.ReadWriteCapacityMode.html) を参照してください。

## アタッチメント
<a name="attachments-ba8175be-9809-4c2e-b2d1-6b9180ed056c"></a>

このドキュメントに関連する追加コンテンツにアクセスするには、[attachment.zip](samples/p-attach/ba8175be-9809-4c2e-b2d1-6b9180ed056c/attachments/attachment.zip) ファイルを解凍してください。