【AWS】AssumeRoleを使用しLambdaから別のAWSアカウント上のAmplify GraphQL APIを操作する方法【クロスアカウントアクセス】

今回は、業務上Lambdaから別アカウントに構築されたAmplifyのDynamoDBテーブルを更新する必要がありその際に少し詰まったので備忘録としてまとめさせていただきました。

今回は、業務上Lambdaから別アカウントに構築されたAmplifyのDynamoDBテーブルを更新する必要がありその際に少し詰まったので備忘録としてまとめさせていただきました。

構成図としては下のようになっています。

実現したいこと: アカウントAのLambdaからアカウントB上にあるAmplifyのDynamoDBにアクセスする。

参考にしたもの:

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

Grant Lambda function access to GraphQL API

アカウントB上でポリシーを作成する

まず、アカウントBのAmplify AppSyncアクセスを許可するポリシーを作成します。

アカウントB上でIAMコンソールを開き、ポリシーを作成まで進んでください。

JSONエディタを開き下のように設定します。

こんな感じです。

AppSync API ARNを入れてください。

作成できましたら次に進みます。

アカウントB上でロールを作成する

次にアカウントAがアカウントBにアクセスする権限を付与する必要があります。

アカウントB上でIAMコンソールを開き、ロールを作成します。

信頼されたエンティティタイプを選ぶ欄でAWSアカウントを選び、別のアカウントのアカウントIDを入力します。

その後次へを押し先程作成したポリシーをアタッチします。

そうしましたらロールの名前を入力してロールを作成してください。
作成できたらそのロールのARNをメモってください。

このロールは後ほど編集する必要がありますが、一旦次にいきます。

アカウントA上でポリシーを作成

アカウントAでアカウントBにアクセスするためのポリシーを作成する必要があります。
アカウントA上でIAMコンソールを開き、ポリシーを作成します。
JSONエディタで下のように設定します。

先程作成したロールのARNを入れてください。
作成できましたら次に進みます。

アカウントA上でロールを作成する

Lambdaに紐付けるロールを作成します。

信頼されたエンティティタイプでAWSサービスを選びユースケースとしてはLambdaを選択してください。
先程作成したポリシーをアタッチし次へ進みます。

そのまま名前をつけて確認し、作成してください。

アカウントA上でLambdaを作成

では、いよいよLambdaを作成します。

既存のロールを使用するを選んで先程作成したロールを紐づけてください。そうしましたらコーディングします。

ランタイムはNode 16です。

実際に私が業務上作成したLambdaを簡易化したものになります。

コードの説明としてはAssumeRoleを取得した後DynamoDB上のTodoテーブルを更新するLambdaになっています。

環境変数にASSUME_ROLE_ARNとREGIONとAPPSYNC_URLを設定してあげてください。

ひとまずテストしてみます。

AccessDenied: User: [arn:aws:sts::[アカウントBのID]:assumed-role/[アカウントBのロール名]/[ロールセッション名]] is not authorized to perform: sts:AssumeRole on resource: [アカウントBのAssumeRoleARN]

私の前に立ちはだかった第一の壁がこのエラーです。
もしかしたらこの記事を見に来てくれた人の中にも出てきたんじゃないでしょうか?

このエラーはarn:aws:sts::[アカウントBのID]:assumed-role/[アカウントBのロール名]/[ロールセッション名]に[アカウントBのAssumeRoleARN]を実行する権限がないことを示しています。

解決方法は、こちらで作成したアカウントBのロールを開き、信頼関係から信頼ポリシーを編集することで解決します。

また、作成した際に別のAWSアカウントIDを記載した際に自動で設定されたルートユーザの情報を信頼ポリシーから削除してアカウントAで実行するLambdaロールのARNを入れましょう。

ルートユーザを信頼関係に含めることは最小権限の原則に則っておらず、アンチパターンとなっております。

“arn:aws:sts::[アカウントBのID]:assumed-role/[このロール名]/[Lambdaで設定するロールセッション名]”を信頼関係に追加してください。

これでAssumeRoleの取得に関しては解決します。

では、もう一度テストしてみましょう。

Error: GraphQL error: Not Authorized to access [GraphQL Query] on type Mutation

次に立ちはだかった第二の壁はこちらです。

要はアクセス権限がないと出ているのですが、ロールの設定もしたしSchema.graphqlでも{ allow: private, provider: iam }を設定してあるしと途方に暮れました。

しかしこちらのエラーは「/amplify/backend/api/[API名]/custom-roles.json」を追加してあげると実行できるようになります。
具体的にはこちらに書いてあります。

“arn:aws:sts::「アカウントBのID」:assumed-role/「アカウントBのロール名」”を明示して上げる必要があります。

私はここにアカウントBのロールARNを入れてしまっていてかなり途方に暮れました。

ご注意ください。

「custom-roles.json」が作成できましたら

$ amplify push

して反映させてあげてください。

これで無事DynamoDBを別アカウントからアクセスすることができました。

 

まとめ

Amplify アプリのDynamoDBテーブルを更新するには、AssumeRoleを作成し、custom-roles.jsonに明示する必要があります。
こんな回りくどいやり方をせずともAppSyncAPIKeyを使用して直接操作する方法もありますが、漏洩した場合のセキュリティリスクとクォータによる制限がありますのであまりおすすめできません。


もし使ってる場合はこちらの記事を参考にAssumeRoleからの方法に変更することをおすすめします。

この記事がどなたかの助けになれば幸いです。

 

この記事が気に入ったら
いいね ! しよう

Twitter で

【採用情報】一緒に働く仲間を募集しています

採用情報
ページトップへ