サーバーレスAPI作成で500エラー、設定を見直して API Gateway → Lambda のリソースベースポリシーを最小権限で付与してみた

サーバーレスAPI作成で500エラー、設定を見直して API Gateway → Lambda のリソースベースポリシーを最小権限で付与してみた

はじめに

こんにちは、カスタマーサクセス部の奥井大和/やまとです。
AWS Lambda + API Gateway + DynamoDB でサーバーレスAPIを構築中、正しく設定したはずが 500 Internal Server Error が返り続けました。
本記事では、その原因と解決方法について記載します。

先に結論

API GatewayからLambdaを呼び出すリソースベース権限が不足していました。
以下のコマンドで解決できます:

aws lambda add-permission \
  --function-name <Lambda関数名> \
  --statement-id apigw-invoke-permission \
  --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:<リージョン>:<アカウントID>:<API-ID>/*/*"

環境情報

構築していたアプリケーション

  • 目的: テスト開発用ノート管理APIの構築(CRUD操作)
  • 構成:
    • API Gateway (HTTP API)
    • Lambda関数 (Python 3.13)
    • DynamoDBテーブル
    • リージョン: ap-northeast-1
  • 操作: AWS CloudShell

事前設定済み内容

  • DynamoDBテーブル作成済み(状態: ACTIVE)
  • IAMロール作成済み
  • IAMポリシー設定済み(DynamoDB、CloudWatch Logsへのアクセス権限)
  • Lambda関数デプロイ済み
  • 環境変数設定済み
  • API Gatewayルート設定済み(GET/POST/PUT/DELETE)
  • Lambda統合設定済み

発生した問題

症状

入力:curlでAPIにリクエストを送信

curl -X POST <https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/notes> \
  -H "Content-Type: application/json" \
  -d '{"title":"Test Note","content":"Hello API!"}'

出力:500エラー

{"message":"Internal Server Error"}

デバッグ

1:Lambdaコードの簡略化(AWS マネジメントコンソールで変更)

def handler(event, context):
    return {
        "statusCode": 200,
        "body": json.dumps({"message": "Hello World"})
    }

結果:それでも500エラーが継続

2:IAM権限の確認

aws iam get-role-policy --role-name <ロール名> --policy-name <ポリシー名>

結果:DynamoDBとCloudWatch Logsへの権限は正しく設定されていた

3:Lambda単体テスト

aws lambda invoke --function-name <関数名> response.json

結果:Lambda単体では正常に動作している

原因の分析

AWSの権限構造

AWSの権限構造

AWSでは以下の2種類の権限設定が必要です:

  1. 実行ロール(IAMロール): Lambdaが他のAWSサービスにアクセスするための権限
  2. リソースベース権限: 他のAWSサービスがLambdaを呼び出すための権限

今回は後者のリソースベース権限が未設定でした。

エラーパターンの識別方法

症状 原因
500エラー + Lambda単体テスト成功 API Gateway → Lambda の権限不足
500エラー + Lambda単体テスト失敗 Lambdaコード自体のエラー
403エラー API Gatewayの認証・認可設定の問題
タイムアウト Lambda実行時間超過

解決手順

1. 権限の追加

入力:

aws lambda add-permission \
  --function-name <Lambda関数名> \
  --region ap-northeast-1 \
  --statement-id apigw-invoke-permission \
  --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:ap-northeast-1:<アカウントID>:<API-ID>/*/*"

2. 権限設定の確認

入力:

aws lambda get-policy --function-name <Lambda関数名> --region ap-northeast-1

3. 動作確認

入力:curlでAPIにリクエストを送信

curl -X POST <https://xxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/notes> \
  -H "Content-Type: application/json" \
  -d '{"title":"Test Note","content":"Hello API!"}'

出力:正常なレスポンスを確認

{"id":"xxx","title":"Test Note","content":"Hello API!","created_at":"2025-08-21T12:01:02.252131"}

予防と対策

構築時のチェック

入力:

# Lambda関数の単体実行確認
aws lambda invoke --function-name <関数名> response.json

# API Gateway → Lambda の権限確認
aws lambda get-policy --function-name <関数名>

# Lambda実行ロールの権限確認
aws iam get-role-policy --role-name <ロール名> --policy-name <ポリシー名>

構築方法による権限設定の違い

構築方法 リソースベース権限の設定
AWSコンソール 自動設定
CLI/CloudFormation/Terraform 手動設定が必要
SAM/Serverless Framework 自動設定

今回はAWS CloudShellで実行したため、権限設定につまづいてしまいました。

トラブルシューティングフロー

  1. Lambda単体テストで動作確認
  2. API Gateway経由でのテスト
  3. 権限設定の確認をする(リソースベース権限と実行ロール)
  4. 簡略化コードでの問題切り分ける

まとめ

API Gateway + Lambda構成で500エラーが発生し、Lambda単体では正常動作する場合、API GatewayからLambdaを呼び出すリソースベース権限の不足を疑うべきでしょう。
こちらを解決するにはlambda add-permissionコマンドによる権限付与することです。
今回、サーバーレスアーキテクチャでは、サービス間の権限設定が重要なポイントとなることを学びました。
本記事が少しでも参考になりましたら幸いです。

参考

公式ドキュメント:
API Gateway API を使用した Lambda エラーの処理
Amazon API Gateway エンドポイントを使用した Lambda 関数の呼び出し
チュートリアル: API Gateway で Lambda を使用する

アノテーション株式会社について

アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。

この記事をシェアする

facebookのロゴhatenaのロゴtwitterのロゴ

© Classmethod, Inc. All rights reserved.