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

awsアプリケーション開発

当記事では、Lambdaで別アカウント作成されたDynamoDBのテーブルにアクセスする方法について紹介します。

Z-A-K-I
Z-A-K-I

AWSで開発を始めたが別アカウントのDynamoDBにアクセスする要件が出てきた。

やったことがないので、どういうやり方をすればよいか知りたい。

と、思ってる方におすすめです。

この記事では、以下のことを紹介してます。

  • クロスアカウントとクロスリージョンとは
  • AWS Lambdaとは
  • クロスアカウント・クロスリージョンを実現するためのステップ

AWSを利用したクラウドネイティブの開発では、別アカウントのリソースからデータを取得する要件は頻出します。

本記事では、そのような場合にAWS上でどのような設定をしなければならないかを具体的な手順で紹介しています。また、別アカウントのリソースへのアクセス方法に加えて、別リージョンへのアクセス方法も合わせて紹介します。

クロスアカウントとクロスリージョンとは

クロスアカウントとは、Lambdaを実行するアカウントとは別のアカウントのサービスにアクセスすることを指します。

例えば、Lambdaを実行するアカウントとは別のアカウントで作成されたDynamoDBにアクセスすることがそれにあたります。なおここで記載している「アカウント」と「ユーザ」はAWSに慣れていない利用者には間違われがちですので、簡単に説明すると、


 「アカウント」=契約単位。「ユーザ」=アカウント内のログインユーザ。

このような感じです。

クロスリージョンとは、Lambdaを実行するリージョンとは別のリージョンのサービスにアクセスすることを指します。

例えば東京リージョンのLambdaから北部バージニアリージョンのDynamoDBにアクセスすることがそれにあたります。

AWS Lambdaとは

AWSが提供するサーバーレスのプログラムを実行するサービスです。

詳細は、以下記事で紹介しておりますのでこちらを参照ください。

クロスアカウント・クロスリージョンを実現するためのステップ

作業のステップを記載します。

説明をわかりやすくするために、ここでは以下のアカウントを定義します。

  • アカウントA(DynamoDBにアクセスする側:Lambdaを作成するアカウント)
  • アカウントB(Lambdaにアクセスされる側:DynamoDBのテーブルを作成するアカウント)

各アカウントのリソースにはセキュリティ上、他のアカウントからアクセスできないように閉じられています。

クロスアカウントアクセスでは、アクセスを許可するために「信頼関係」を設定する必要があります。

「信頼関係」とは特定のアカウントに特定の操作を許可する設定の総称です。

今回の場合は、「アカウントB」に「アカウントA」からは「DynamoDBを読み取る操作」を許可するという信頼関係を設定します。この信頼関係はIAMでロールを作成することになります。

以下のステップとなります。

  1. アカウントBに信頼関係のロールを作成
  2. アカウントAに「1」で作成したロールにAssumeRoleするポリシーを作成
  3. アカウントAに「2」で作成したポリシーを設定したロールを作成。
    ※Lambda(アカウントBのDynamoDBテーブルにアクセスするLambda)に設定するロール
  4. アカウントAのLambda(アカウントBのDynamoDBテーブルにアクセスするLambda)に「3」のロールを設定。

次からは各ステップの設定内容を記載していきます。

アカウントBに信頼関係のロールを作成

以下手順でアカウントAがアカウントBのDynamDBのテーブルにアクセスを許可する信頼関係(ロール)を作成します。

アカウントBでAWS Consoleにログインし、IAMのサービスに移動します。移動後、「ロールを作成」ボタンからロールを作成していきます。

アカウントBに信頼関係のロールを作成

次へボタンをクリックし、「DynamoDB」を検索。Readアクセスにチェックし、次へボタンクリック。

アカウントBに信頼関係のロールにDynamoDBのポリシーを設定

ロール名をわかりやすい名称「DynamoDBReadAccess-For-AccuntA」を設定し、ロールを作成する

アカウントBに信頼関係のロール名の設定

アカウントAに「1」で作成したロールにAssumeRoleするポリシーを作成

アカウントAに上で作成したアカウントBのロールを利用するポリシーを作成していきます。

あらかじめ、アカウントBで上で作成したロールのARNをコピーしておきます。

アカウントAにログインし、AWS ConsoleでIAMのサービスに移動します。

「ポリシーの作成」ボタンをクリックし、ポリシーを作成していきます。JSONでの編集モードにして以下を設定していきます。塗りつぶされている箇所はアカウントBのアカウントIDです。

各環境に応じて変更してください。

アカウントAにAssumeRoleするポリシーを作成

上で設定するポリシー

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "sts:AssumeRole",
            "Resource": "arn:aws:iam::アカウントBのARN:role/DynamoDBReadAccess-For-AccuntA"
        }
    ]
}

「次へ」ボタンを押下し以下の画面でポリシー名をわかりやすい名称にし、ポリシーを作成します。

今回は、アカウントBのDynamoDBにアクセスするポリシーということで「DynamoDBReadAccess-For-AccuntB」としています。

アカウントAに作成したロールに名前を設定

ポリシーの作成ボタンをクリックし、ポリシーを作成します。

アカウントAに「2」で作成したポリシーを設定したロールを作成。

次はアカウントAにアカウントBのDynamoDBを読み取ることができるロールを作成していきます。

通常のLambdaを実行する権限に追加して、上で作成したポリシーをロールに設定してきます。
アカウントAのIAMサービスからロールを作成していきます。

エンティティタイプを「AWS サービス」にし、ユースケースに「Lambda」を選択し次へボタンをクリック。

アカウントAに作成するロールの設定

上で作成したポリシー「DynamoDBReadAccess-For-AccuntB」を選択し次へボタンをクリック。

アカウントAに作成する、ロールに設定するポリシーの設定

ロール名に検証用のロールという意味で「Verificataion-AccountB-DynamoDB-Role」を設定し、ロールを作成します。

アカウントAに作成する、ロールに設定するポリシーの名前

アカウントAのLmbda(アカウントBのDynamoDBテーブルにアクセスするLambda)に「3」のロールを設定。

アカウントAのLambdaプログラムのロールに上記で作成した「Verificataion-AccountB-DynamoDB-Role」を設定し作成します。

デプロイするLambdaのプログラムは後述します。

アカウントBのDynamoDBにアクセスするLambdaプログラムの作成

JavaでLambdaプログラムを作成します。

ここではクロスアカウント・クロスリージョンのDynamoDBにアクセスするための簡単なコードを記載します。

Lambdaでは珍しくJavaで検証しております。開発環境は下記リンクを参照ください。

以下のコードを記載することでアカウントBのDynamoDBのテーブルからデータを取得することが可能です。

AmazonDynamoDBオブジェクトを作成する時に、アカウントBにAssumeRoleした認証情報を設定することで、アカウントBのDynamoDBテーブルにアクセスすることが可能です。

AmazonDynamoDB amazonDYnamoDBClient;

String roleArn = "arn:aws:iam::アカウントBのARN:role/DynamoDBReadAccess-For-AccuntA"";
String roleSessionName = "mySession";

AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClient.builder().withRegion("us-east-1").build();

AssumeRoleRequest roleRequest = new AssumeRequest().withRoleArn(roleArn).withRoleSessionName(roleSessionName);

AssumeRoleResult roleResponse = stsClient.assueRole(roleRequest);

// 認証情報作成
Credentials myCreds = roleResponse.getCredentials();
String key = myCreds.getAccessKeyId();
String secKey = myCreds.getSecretAccessKey();
String secToken = myCreds.getSessionToken();
BasicSessionCredentials awsCreds = new BasicSessionCredentials(key,secKey,secToken):

// 認証情報を使ってDBクライアントを作成
amazonDynamoDBClient = AmazonDynamoDBClient.builder().withRegion("us-east-1").withCredentials(new AWSStaticCredentialsProvider(awsCreds)).build();

// テーブルへのMapperを作成
DynamoDBMapper mapper = new DynamoDBMapper(amazonDynamoDBClient);
DynamoDBScanExpression queryExpression = new DynamoDBScanExpression():

// データの取得
try{
    var responseList = mapper.scan(TestTableData.class, queryExpression):
}catch(Exception e){
    System.out.println("エラーが発生しました"):
}

TestTableDataクラス

@NoArgsConstructor
@Getter
@Setter
@ToString
@DynamoDBTable(tableName="test-table")
public class TestTableData{
  @DynamoDBHashKey(attributeName="pk1")
  private String pk1;

  @DynamoDBAttribute(attributeName="name")
  private String name;

}

利用するAWSのSDKは「com.amazonaws」を利用しています。

pom.xmlに設定して、mavenコマンドでSDKをインストールしてください。

クロスアカウントアクセスの設定をすれば別アカウントのクロスリージョンへは何も設定せずにアクセスすることが可能です。

まとめ

別アカウントのDynamoDBにクロスアカウントアクセスする方法のまとめ

本記事では、AWSでクロスアカウント・クロスリージョンのDynamoDBテーブルからデータを取得する具体的な方法を紹介しました。

本記事を書いた検証を行う前までは、クロスアカウント・クロスリージョンの実現方法が全く知らなかったので、今回の検証で自分自身の知識が深まりました。

本記事が、皆様の参考となりましたら幸いです。

z_a_k_i
この記事を書いた人

z_a_k_iと申します。

富山でITエンジニアとして働いています。
0歳児と3歳児を持つ30代メンズです。

このブログでは、以下の内容を紹介しています。

 ⚫︎アプリケーション開発
 ⚫︎富山県の情報発信

皆様に役立つ内容を紹介できるよう精進していきますので、
どうぞよろしくお願いします。

z_a_k_iをフォローする
awsアプリケーション開発

コメント

タイトルとURLをコピーしました