API Gateway REST API を Amazon SQS と統合して、よくあるエラーを解決する方法を教えてください。
Amazon API Gateway REST API を Amazon Simple Queue Service (Amazon SQS) と統合したいと考えています。また、統合エラーのトラブルシューティングもしたいと考えています。
解決方法
ユーザーは、Amazon SQS と連携して統合ソリューションを作成できるように API Gateway REST API を設定します。
REST API と Amazon SQS 統合をセットアップする
API ゲートウェイ REST API を Amazon SQS と統合するには、次の手順に従います。
1. SQS キューを作成します。
2. AWS Identity and Access Management (AWS IAM) ロールを作成し、SendMessage 権限を持つ Amazon SQS ポリシーをアタッチします。このポリシーにより、API からのメッセージを Amazon SQS に公開することができます。このポリシーでは、example-region を自分の AWS リージョンに、example-account-id をご利用の AWS アカウント ID に、example-sqs-queue-name を自分の SQS キュー名に置き換えてください。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Resource": [ "arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name" ], "Action": [ "sqs:SendMessage" ] } ] }
3. API Gateway で REST API を作成します。
4. API Gateway コンソールで、新しく作成した REST API 用の Amazon SQS インテグレーションを作成します。
- オプションで、REST API リソースまたは REST API メソッドを作成します。
- POST メソッドを作成します。
[Integration type] (統合タイプ) で、[AWS Service] (AWS のサービス) を選択します。
[AWS リージョン] で、ご利用の AWS リージョンを選択します。
[AWS のサービス ] では 、[Simple Queue Service (SQS)] を選択します。
(オプション) AWS Subdomain に、AWS のサービスで使用されるサブドメインを入力します。AWS のサービスのドキュメント をチェックし、サブドメインの可用性を確認します。Amazon SQS のサンプルセットアップでは、これを空白のままにします。
[HTTP メソッド] で、[POST] を選択します。
[アクションの種類] で [パス上書きの使用] を選択します。
[パス上書き (省略可能)] には、アカウント ID と SQS キュー名を example-account-id/example-sqs-queue-name の形式で入力します。例えば、1234567890/MySQSStandardQueue などです。
実行ロール に、ステップ 2 で作成した IAM ロールの ARN を入力します。
[コンテンツハンドリング] では、セットアップに合ったオプションを選択します。
[Default Timeout] (デフォルトタイムアウト) をクリアまたは選択します。セットアップに合ったオプションを選択します。
新しい POST メソッドを保存します。 - REST API インテグレーション情報の入力を続けます。
POST メソッドの [Integration Request] (統合リクエスト) を選択します。
[HTTP Headers] (HTTP ヘッダー) を展開します。
[Add header] (ヘッダーの追加) を選択します。
[名前] に「Content-Type」と入力します。
[マップ元] にapplication/x-www-form-urlencodedと入力して [作成] を選択します。
[マッピングテンプレート] を展開します。
[Request body passthrough] (リクエストボディパススルー) では、要件に合ったオプションを選択します。
[マッピングテンプレートの追加] を選択します。
[コンテンツタイプ] に「application/json」と入力してから、[作成] を選択します。
テンプレートには、「action=sendMessage&MessageBody=$input.body」と入力します。
5. API Gateway に次のリクエストを送信して、セットアップをテストします。example-api-id を自分の API ID に、example-region を AWS リージョンに、example-stage をテストステージ名に、example-resource を自分のリソース名に置き換えます。
curl --location --request POST 'https://example-api-id.execute-api.example-region.amazonaws.com/example-stage/example-resource' \ --header 'Content-Type: application/json' \ --data-raw '{ "message": "Hello World" }'
統合が成功すると、次のような応答が表示されます。
{ "SendMessageResponse": { "ResponseMetadata": { "RequestId": "f879fb11-e736-52c0-bd29-a0f2d09ad90d" }, "SendMessageResult": { "MD5OfMessageAttributes": null, "MD5OfMessageBody": "3fc759ac1733366f98ec4270c788fcd1", "MD5OfMessageSystemAttributes": null, "MessageId": "4c360c3c-08f4-4392-bc14-8b0c88e314a2", "SequenceNumber": null } } }
よくあるエラーの解決
UnknownOperationException エラー
UnknownOperationException エラーは、ユーザーが統合リクエストの HTTP ヘッダーでコンテンツタイプを "application/x-www-form-urlencoded" として構成しなかった場合に発生します。UnknownOperationException エラーは、SendMessage アクションが統合リクエストマッピングテンプレートに追加しない場合にも発生します。
AccessDenied エラー
以下は AccessDenied エラーの例です。
{ "Error": { "Code": "AccessDenied", "Message": "Access to the resource https://sqs.example-region.amazonaws.com/example-account-id/example-sqs-queue-name is denied.", "Type": "Sender" }, "RequestId": "92aea8b7-47f1-5bd4-b3c4-f3d0688d3809" }
API 統合の実行ロールに、SQS キューにメッセージを送信するための sqs:SendMessage 権限が設定されていない場合に、AccessDenied エラーが発生します。AccessDenied エラーは、リクエスト本文のペイロードに「&」や「%」などの特殊文字が渡された場合にも発生する可能性があります。渡すには特殊文字をエンコードする必要があります。マッピングテンプレートに $util.urlEncode() 関数を追加して、リクエスト本文を文字列からエンコードされた形式に変換します。以下はマッピングテンプレートの例です。
Action=SendMessage&MessageBody=$util.urlEncode($input.body)
次の例には、SQS キューにメッセージを送信するために必要な権限が含まれています。example-region を自分の AWS リージョンに、example-account-id を AWS アカウント ID に、example-sqs-queue-name を SQS キュー名に置き換えてください。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Resource": [ "arn:aws:sqs:example-region:example-account-id:example-sqs-queue-name" ], "Action": [ "sqs:SendMessage" ] } ] }
KMS.AccessDeniedException エラー
次に、KMS.AccessDeniedException エラーの例を 2 つ示します。
{ "Error": { "Code": "KMS.AccessDeniedException", "Message": "User: arn:aws:sts::example-account-number:assumed-role/example-sqs-queue-name/BackplaneAssumeRoleSession is not authorized to perform: kms:GenerateDataKey on resource: arn:aws:kms:example-region:example-account-number:key/example-keyId because no identity-based policy allows the kms:GenerateDataKey action (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: c58f1eec-6b18-4029-826b-d05d6a715716; Proxy: null)", "Type": "Sender" }, "RequestId": "99976a6a-3311-57e9-86e9-310d0654ff80" }
{ "Error": { "Code": "KMS.AccessDeniedException", "Message": "The ciphertext refers to a customer master key that does not exist, does not exist in this region, or you are not allowed to access. (Service: AWSKMS; Status Code: 400; Error Code: AccessDeniedException; Request ID: a8adea02-c246-49d9-8b3d-ff6b6a43b40f; Proxy: null)", "Type": "Sender" }, "RequestId": "9565c451-742c-55f3-a1eb-9f3641fd30aa" }
KMS.AccessDeniedException エラーは、API 統合実行ロールが AWS Key Management Service (AWS KMS) を介して操作を実行できない場合に発生します。Amazon SQS サーバー側の暗号化キューにアタッチされている AWS KMS キーで操作を実行するには、アクセス権限を設定する必要があります。
次の例には、SQS キューに接続されている KMS キーを操作するために必要な権限が含まれています。example-account-id を自分の AWS アカウント ID に置き換え、example-api-gw-integration-execution-role を自分の実行ロール名に置き換えます。
{ "Sid": "Allow use of the key", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::example-account-id:role/example-api-gw-integration-execution-role" }, "Action": [ "kms:Encrypt", "kms:GenerateDataKey*", "kms:Decrypt" ], "Resource": "*" }
関連するコンテンツ
- 質問済み 4年前lg...
- 承認された回答質問済み 9ヶ月前lg...
- 質問済み 4ヶ月前lg...
- AWS公式更新しました 1年前