1
0

More than 1 year has passed since last update.

異なるリージョンでサービスを連携させようとしてAccessDeniedExceptionを発生させた話

Last updated at Posted at 2021-11-01

今回は、公式サイトのチュートリアルに記載されていた簡単なWebアプリケーションを作成しようとした際にサービス間の連携がうまくできずエラーになってしまったので原因と解決方法をこちらに備忘メモとして記載したいと思います。

こちらのチュートリアルに則って作成しました。
手順は以下のモジュール1~5の流れとなります。

モジュール 1: ウェブアプリケーションを作成する

・Amplify コンソールでウェブアプリを作成
・ウェブアプリをテストする

モジュール 2: サーバーレス関数を構築する

・PythonでAWS コンソールを使用して Lambda 関数を一から作成する
・AWS コンソールで (JSON) イベントを作成して関数をテストする

モジュール 3: サーバーレス関数をウェブアプリケーションにリンクする

・API Gateway を使用して新しい API を作成する
・API で HTTP (ハイパーテキスト転送プロトコル) メソッドを定義する
・API から Lambda 関数をトリガーする
・API で CORS を有効にして、ウェブサイトから使用できるようにする
・AWS マネジメントコンソールから API Gateway で作成された API をテストする

モジュール 4: データテーブルを作成する

・AWS マネジメントコンソールで DynamoDB テーブルを作成する
・IAM でロールを作成し、アクセス許可を管理する
・AWS SDK (Python、JavaScript、または Java) を使用して DynamoDB テーブルに書き込む

モジュール 5: ウェブアプリケーションに対話性を追加する

・HTML ページから API Gateway API を呼び出す
・Amplify コンソールにウェブアプリケーションの新しいバージョンをアップロードする

各モジュール実行結果

モジュール1実行時スクショ
モジュール1_失敗ver_編集後.jpg
モジュール2実行時スクショ
モジュール2_失敗2_編集後.jpg
モジュール3実行時スクショ
モジュール3_失敗_API作成_オレゴン4編集後.jpg

ここまでは順調だったのですが、
モジュール4内最後の手順、「変更をテストする」の箇所でテストを実行するとエラーが発生してしまいました。

モジュール4実行時スクショ
モジュール4_失敗4編集後.jpg

エラー内容を確認すると、AccessDeniedExceptionが発生しており、
DBのarnの認証がうまくいっていない旨のメッセージが表示されています。

(AccessDeniedException) when calling the PutItem operation: User: arn:aws:sts::(IAMに設定しているロールのARN) is not authorized to perform

なぜ認証が通っていないのか?

原因として考えられること
・各サービスの設定がうまくいっていない
→各設定の見直し、再度作り直しを行ったが変化無しでした。
・リージョンが異なっている
→dynamoDBを確認してみるとリージョンが「バージニア北部」になっていました。

そこで「オレゴン」のDynamodbを確認してみると以下のように表示されました。
モジュール4_失敗5編集後.jpg

Lambdaで呼び出しているテーブルが見つからない旨のエラーが出ていました(CloudWatchなどではこのような内容のログが無かったので気づきませんでした)。

そこでオレゴンリージョンのDynamoDBにHelloWorldDatabaseテーブルを作成し、モジュール4でIAMポリシーに追加していたインラインポリシーを修正することに...

修正前
{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "VisualEditor0",
        "Effect": "Allow",
        "Action": [
            "dynamodb:PutItem",
            "dynamodb:DeleteItem",
            "dynamodb:GetItem",
            "dynamodb:Scan",
            "dynamodb:Query",
            "dynamodb:UpdateItem"
        ],
        "Resource": "バージニア北部のリージョンで作成したテーブルの ARN "
    }
    ]
}
修正後
{
"Version": "2012-10-17",
"Statement": [
    {
        "Sid": "VisualEditor0",
        "Effect": "Allow",
        "Action": [
            "dynamodb:PutItem",
            "dynamodb:DeleteItem",
            "dynamodb:GetItem",
            "dynamodb:Scan",
            "dynamodb:Query",
            "dynamodb:UpdateItem"
        ],
        "Resource": "オレゴンのリージョンで作成し直したテーブルの ARN "
    }
    ]
}

すると
無事起動できました!
API実行成功.jpg

今回の原因

別のリージョンにあっても、同じリージョン内のDynamoDBには何もなかったので連携対象が無いとしてエラーが発生してしまっていました。

こちらのサイトを見ることでリージョンについて理解できました(公式の方にも説明があったかもしれないですが・・・)。
各「リージョン」ではAWSのサービスがそれぞれ独立して提供されており、言い方を変えると「リージョン」はお互いに完全に分離されるよう設計されたAWSのネットワークとサービスの「集合」となります。

つまり、今回作成したアプリの構成が
構成図1.jpg

上記ではなく、以下のようになってしまっていました。
構成図2.jpg

クラウドを日常的に業務で使用している方やクラウドの概念をしっかり理解している方は躓かないところだと思うのですが、リージョンに対して「地理的に離れた領域」であるという認識だけで各「リージョン」ではAWSのサービスがそれぞれ独立して提供されているということを知らないと、複数のサービスを連携させる際に各設定は間違っていないはずなのにうまく動かないという事態が発生してしまうかもしれません(そんなことをするのは私くらいかもしれないですが…)。
今後注意したいと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0