Amazon DynamoDB へのクロスアカウントアクセスを設定する - AWS 規範ガイダンス

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

Amazon DynamoDB へのクロスアカウントアクセスを設定する

作成者: Shashi Dalmia (AWS) and Jay Enjamoori (AWS)

環境:本稼働

テクノロジー: DevOps、データベース、セキュリティ、アイデンティティ、コンプライアンス

AWS サービス:Amazon DynamoDB、AWS Identity and Access Management、AWS Lambda

[概要]

このパターンは、Amazon DynamoDB へのクロスアカウントアクセスを設定手順を説明しています。Amazon Web Services (AWS) サービスは、データベースで適切な AWS Identity and Access Management (IAM) アクセス許可が設定されていれば、同じ AWS アカウントにある DynamoDB テーブルにアクセスできます。ただし、別の AWS アカウントからアクセスするには、IAM アクセス許可を設定し、2 つのアカウント間の信頼関係を確立する必要があります。

このパターンでは、あるアカウントで AWS Lambda 関数を設定して、別のアカウントの DynamoDB テーブルに対して読み取りと書き込みを行う方法を示す手順とサンプルコードを示します。

前提条件と制限

  • 2 つのアクティブな AWS アカウント。このパターンでは、これらのアカウントを「アカウント A」と「アカウント B」と呼びます。

  • AWS コマンドラインインターフェイス (AWS CLI) を「インストール」し、アカウント A にアクセスするように「設定」し、DynamoDB データベースを作成します。このパターンの他のステップでは、IAM、DynamoDB、および Lambda コンソールの使用手順について説明します。代わりに AWS CLI を使用する予定の場合は、両方のアカウントにアクセスするように設定します。

アーキテクチャ

以下の図では、AWS Lambda、Amazon EC2、DynamoDB、DynamoDB はすべて同じアカウントにあります。このシナリオでは、Lambda 関数と Amazon Elastic Compute Cloud (Amazon EC2) インスタンスが DynamoDB にアクセスできます。

同じアカウントから DynamoDB にアクセスする

別の AWS アカウントのリソースが DynamoDB にアクセスしようとする場合、クロスアカウントアクセスと信頼関係を設定する必要があります。たとえば、次の図で、アカウント A の DynamoDB とアカウント B の Lambda 関数間のアクセスを有効にするには、「エピック」セクションで説明されているように、アカウント間に信頼関係を作成し、Lambda サービスとユーザーに適切なアクセス権を付与する必要があります。 

別のアカウントから DynamoDB にアクセスする

ツール

AWS サービス

  • Amazon DynamoDB」は、フルマネージド NoSQL データベースサービスであり、シームレスなスケーラビリティを備えた高速で予測可能なパフォーマンスを提供します。

  • AWS Lambda」 – AWS Lambda はサーバーのプロビジョニングや管理を行わずにコードの実行を支援できるコンピューティングサービスです。Lambda は必要に応じてコードを実行し、1 日あたり数個のリクエストから 1 秒あたり数千のリクエストまで自動的にスケールします。課金は実際に消費したコンピューティング時間に対してのみ発生します。コードが実行されていない場合、料金は発生しません。

  • AWS Identity and Access Management (IAM)」は、AWS リソースへのアクセスを安全に管理し、誰が認証され、使用する権限があるかを制御するのに役立ちます。

Code

このパターンには、アカウント B の Lambda 関数を設定してアカウント A の DynamoDB テーブルへの書き込みと読み取りを行う方法を示すサンプルコードが「追加情報」セクションに含まれています。このコードは説明とテストのみを目的としています。このパターンを本番環境に実装する場合は、コードをリファレンスとして使用し、自分の環境に合わせてカスタマイズしてください。

このパターンは、Lambda と DynamoDB によるクロスアカウントアクセスを示しています。他の AWS サービスでも同じ手順を使用できますが、両方のアカウントに適切な権限を付与し、設定していることを確認してください。たとえば、アカウント A の Amazon Relational Database Service (Amazon RDS) データベースへのアクセスを許可したい場合は、そのデータベースのロールを作成し、信頼関係にバインドします。アカウント B で、AWS Lambda の代わりに Amazon EC2 を使用する場合は、それぞれの IAM ポリシーとロールを作成し、それらを EC2 インスタンスにアタッチします。

エピック

タスク説明必要なスキル

アカウント A でDynamoDB テーブルを作成します。

アカウント A 用に AWS CLI を設定したら、次の AWS CLI コマンドを使用して DynamoDB テーブルを作成します。

aws dynamodb create-table \ --table-name Table-Acccount-A \ --attribute-definitions \ AttributeName=category,AttributeType=S \ AttributeName=item,AttributeType=S \ --key-schema \ AttributeName=category,KeyType=HASH \ AttributeName=item,KeyType=RANGE \ --provisioned-throughput \ ReadCapacityUnits=5,WriteCapacityUnits=5

テーブルの作成の詳細については、「DynamoDB のドキュメント」を参照してください。

AWS DevOps
タスク説明必要なスキル

アカウント A でロールを作成します。

アカウント B がこのロールを使用してアカウント A にアクセスする許可を取得します。ロールを作成するには:

  1. https://<account-ID-for-Account-A>.signin.aws.amazon.com/console でアカウント A にサインインします。

  2. IAM コンソール (https://console.aws.amazon.com/iam/) を開きます。

  3. コンソールのナビゲーションペインで、[ロール]、[ロールの作成] の順に選択します。

  4. [信頼されたエンティティの選択] の場合は、[AWS アカウント] を選択し、「AWS アカウント」セクションで [別の AWS アカウント] を選択します。

  5. [アカウント ID] には、アカウント B の ID を入力します。

  6. [次へ: アクセス許可] を選択します。

  7. [フィルタポリシー] ボックスに DynamoDB と入力します。

  8. DynamoDB ポリシーのリストで、AmazonDynamoDB FullAccessを選択します。

    注:このポリシーは、DynamoDB でのすべてのアクションを許可します。セキュリティのベストプラクティスとしては、常に必要なアクセス許可のみを付与してください。代わりに選択できる他のポリシーのリストについては、IAM ドキュメントの「ポリシーの例」を参照してください。

  9. [次へ:名前、確認、および作成] を選択します。

  10. ロール名 には、ロールの一意の名前 (DynamoDB -FullAccess-For-Account-B など) を入力し、オプションのロールの説明を追加します。

  11. すべてのセクションを確認し、(オプションで)タグをキーと値のペアでアタッチして、ロールにメタデータを追加します。

  12. [ロールの作成] を選択します。

ロールの作成の詳細については、「IAM ドキュメント」を参照してください。

AWS DevOps

アカウント A のロールの ARN をメモしてください。

  1. IAM コンソールのナビゲーションペインで [ロール] を選択します。

  2. 検索ボックスに、DynamoDB -FullAccess-For-Account-B (または前のストーリーで作成したロール名) を入力し、ロールを選択します。

  3. ロールの概要ページで、Amazon リソースネーム (ARN) をコピーします。ARN は、アカウント B で Lambda コードを設定するときに使用します。

AWS DevOps
タスク説明必要なスキル

アカウント A にアクセスするポリシーを作成します。

  1. https://<account-ID-for-Account-B>.signin.aws.amazon.com/console でアカウント B にサインインします。

  2. IAM コンソール (https://console.aws.amazon.com/iam/) を開きます。

  3. コンソールのナビゲーションペインで、[ポリシー]、[ポリシーの作成] の順に選択します。

  4. [JSON] タブを選択します。

  5. 次の JSON ドキュメントを入力または貼り付けます。

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::<Account-A-ID>:role/DynamoDB-FullAccess-For-Account-B" } ] }

    Resource プロパティには、前のストーリーでアカウント A で作成したロールの ARN が含まれます。

  6. [次へ: タグ] を選択します。

  7. (オプション) タグをキー - 値のペアとしてアタッチして、メタデータをポリシーに追加します。

  8. [次へ: 確認] を選択します。

  9. ポリシー名 には、ポリシーの一意の名前 (DynamoDB -FullAccess-Policy-in-Account-A など) を入力し、オプションのポリシーの説明を追加します。

  10. [ポリシーの作成] を選択します。

ポリシーの作成の詳細については、「IAM のドキュメント」を参照してください。

AWS DevOps

ポリシーに基づいてロールを作成します。

このロールは、アカウント B の Lambda 関数がアカウント A の DynamoDB テーブルへの読み取りと書き込みに使用されます。

  1. アカウント B の IAM コンソールのナビゲーションペインで、[ロール]、[ロールを作成] の順に選択します。

  2. [Select type of trusted entity (信頼されたエンティティのタイプの選択)] で、[AWS サービス] を選択します。

  3. ユースケースとして、[Lambda] を選択してください。

  4. [次へ: アクセス許可] を選択します。

  5. [フィルタポリシー] ボックスに DynamoDB と入力します。

  6. DynamoDB ポリシーのリストで、前のストーリーで作成した DynamoDB -FullAccess-Policy-in-Account-A を選択します。

  7. [次へ:名前、確認、および作成] を選択します。

  8. ロール名 には、ロールの一意の名前 (DynamoDB -FullAccess-in-Account-A など) を入力し、オプションのロールの説明を追加します。

  9. すべてのセクションを確認し、(オプションで)タグをキーと値のペアでアタッチして、ロールにメタデータを追加します。

  10. [ロールの作成] を選択します。

これで、このロールを次のエピックの Lambda 関数にアタッチできます。

ロールの作成の詳細については、「IAM ドキュメント」を参照してください。

AWS DevOps
タスク説明必要なスキル

DynamoDB にデータを書き込むLambda 関数を作成します。

  1. https://<account-ID-for-Account-B>.signin.aws.amazon.com/console でアカウント B にサインインします。

  2. Lambda コンソール (https://console.aws.amazon.com/lambda/) を開きます。

  3. コンソールのナビゲーションペインで、[関数]、[関数の作成] の順に選択します。

  4. [名前] には、「lambda_write_function」と入力します。

  5. [ランタイム] には、[Python 3.8] またはそれ以降を選択します。

  6. アクセス許可で、[デフォルト実行ロールの変更] を選択し、[既存のロールを使用] を選択します。

  7. 既存のロール で、DynamoDB -FullAccess-in-Account-A を選択します。

  8. [関数を作成]を選択します。

  9. [コード] タブに、このパターンの「追加情報」セクションで提供されている [Lambda write 関数] の [サンプルコード] を貼り付けます。RoleArn フィールドには必ず正しいロール ARN (「アカウント A でロールを作成」のエピックから) を指定し、region_name をアカウント A (「アカウント A に DynamoDB テーブルを作成する」のエピックから) の DynamoDB テーブルの作成場所に変更してください。これを行わないと ResourceNotFoundException エラーが発生します。

  10. コードをデプロイするには、[デプロイ] を選択します。

  11. [テスト] を選択して関数を実行します。これにより、テストイベントを設定するよう求められます。などの任意の名前で新しいイベントを作成しMyTestEventForWrite、設定を保存します。

  12. [テスト] を選択して関数を再実行します。これにより、指定したイベント名でコードが実行されます。

  13. 関数からの出力を確認します。「追加情報」の「Lambda 書き込み関数」セクションに示されている出力と似ているはずです。この出力は、関数がアカウント A の DynamoDB テーブルにアクセスし、データを書き込むことができたことを示しています。

Lambda 関数の作成についての詳細は、「Lambda ドキュメント」を参照してください。

AWS DevOps

DynamoDB からデータを読み取る Lambda 関数を作成します。

  1. Lambda コンソールのナビゲーションペインで、[関数]、[関数の作成] の順に選択します。

  2. [名前] には、「lambda_read_function」と入力します。

  3. [ランタイム] には、[Python 3.8] またはそれ以降を選択します。

  4. アクセス許可で、[デフォルト実行ロールの変更] を選択し、[既存のロールを使用] を選択します。

  5. 既存のロール で、DynamoDB -FullAccess-in-Account-A を選択します。

  6. [関数を作成]を選択します。

  7. [コード] タブに、このパターンの「追加情報」セクションにある [Lambda read 関数] のサンプルコードを貼り付けます。RoleArn フィールドには必ず正しいロール ARN (「アカウント A でロールを作成」のエピックから) を指定し、region_name をアカウント A (「アカウント A に DynamoDB テーブルを作成する」のエピックから) の DynamoDB テーブルの作成場所に変更してください。これを行わないと ResourceNotFoundException エラーが発生します。

  8. コードをデプロイするには、[デプロイ] を選択します。

  9. [テスト] を選択して関数を実行します。これにより、テストイベントを設定するよう求められます。などの任意の名前で新しいイベントを作成しMyTestEventForRead、設定を保存します。

  10. [テスト] を選択して関数を再実行します。これにより、指定したイベント名でコードが実行されます。

  11. 関数からの出力を確認します。「追加情報」の「Lambda read 関数」セクションに示されている出力と似ているはずです。この出力は、関数がアカウント A の DynamoDB テーブルにアクセスし、テーブルに追加したデータを読み取ることができたことを示しています。

Lambda 関数の作成についての詳細は、「Lambda ドキュメント」を参照してください。

AWS DevOps
タスク説明必要なスキル

作成したリソースを削除します。

このパターンをテスト環境または概念実証 (PoC) 環境で実行する場合は、コストが発生しないように作成したリソースを削除してください。

  1. アカウント B で、DynamoDB に接続するために作成した 2 つの Lambda 関数とその他のリソースを削除します。

  2. アカウント A で、作成した DynamoDB テーブルを削除します。

  3. IAM ポリシーには費用はかからないため、そのままにしておくことができます。ただし、セキュリティ上の理由から、このパターンで作成した以下のロールとポリシーを削除することをお勧めします。

    • アカウント A: DymamoDB-Full-Access-for-Account-A ロール

    • アカウント B: DynamoDB -FullAccess-in-Account-A ロール

    • アカウント B: DynamoDB -FullAccess-Policy-in-Account-A ポリシー

AWS DevOps

関連リソース

追加情報

このセクションのコードは、説明とテストのみを目的としています。このパターンを本番環境に実装する場合は、コードをリファレンスとして使用し、自分の環境に合わせてカスタマイズしてください。

Lambda 書き込み関数

サンプルコード

import boto3 from datetime import datetime sts_client = boto3.client('sts') sts_session = sts_client.assume_role(RoleArn='arn:aws:iam::<Account-A ID>:role/DynamoDB-FullAccess-For-Account-B', RoleSessionName='test-dynamodb-session') KEY_ID = sts_session['Credentials']['AccessKeyId'] ACCESS_KEY = sts_session['Credentials']['SecretAccessKey'] TOKEN = sts_session['Credentials']['SessionToken'] dynamodb_client = boto3.client('dynamodb', region_name='<DynamoDB-table-region-in-account-A', aws_access_key_id=KEY_ID, aws_secret_access_key=ACCESS_KEY, aws_session_token=TOKEN) def lambda_handler(event, context): now = datetime.now() date_time = now.strftime("%m/%d/%Y, %H:%M:%S") data = dynamodb_client.put_item(TableName='Table-Acccount-A', Item={"category": {"S": "Fruit"},"item": {"S": "Apple"},"time": {"S": date_time}}) return data

サンプル出力

Lambda 書き込み関数からのサンプル出力

Lambda 読み取り関数

サンプルコード

import boto3 from datetime import datetime sts_client = boto3.client('sts') sts_session = sts_client.assume_role(RoleArn='arn:aws:iam::<Account-A ID>:role/DynamoDB-FullAccess-For-Account-B', RoleSessionName='test-dynamodb-session') KEY_ID = sts_session['Credentials']['AccessKeyId'] ACCESS_KEY = sts_session['Credentials']['SecretAccessKey'] TOKEN = sts_session['Credentials']['SessionToken'] dynamodb_client = boto3.client('dynamodb', region_name='<DynamoDB-table-region-in-account-A>', aws_access_key_id=KEY_ID, aws_secret_access_key=ACCESS_KEY, aws_session_token=TOKEN) def lambda_handler(event, context): response = dynamodb_client.get_item(TableName='Table-Acccount-A', Key={'category':{'S':'Fruit'}, 'item':{'S':'Apple'}}) return response

サンプル出力

Lambda 読み取り関数からのサンプル出力