サーバーレス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では以下の2種類の権限設定が必要です:
- 実行ロール(IAMロール): Lambdaが他のAWSサービスにアクセスするための権限
- リソースベース権限: 他の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で実行したため、権限設定につまづいてしまいました。
トラブルシューティングフロー
- Lambda単体テストで動作確認
- API Gateway経由でのテスト
- 権限設定の確認をする(リソースベース権限と実行ロール)
- 簡略化コードでの問題切り分ける
まとめ
API Gateway + Lambda構成で500エラーが発生し、Lambda単体では正常動作する場合、API GatewayからLambdaを呼び出すリソースベース権限の不足を疑うべきでしょう。
こちらを解決するにはlambda add-permission
コマンドによる権限付与することです。
今回、サーバーレスアーキテクチャでは、サービス間の権限設定が重要なポイントとなることを学びました。
本記事が少しでも参考になりましたら幸いです。
参考
公式ドキュメント:
API Gateway API を使用した Lambda エラーの処理
Amazon API Gateway エンドポイントを使用した Lambda 関数の呼び出し
チュートリアル: API Gateway で Lambda を使用する
アノテーション株式会社について
アノテーション株式会社はクラスメソッドグループのオペレーション専門特化企業です。サポート・運用・開発保守・情シス・バックオフィスの専門チームが、最新 IT テクノロジー、高い技術力、蓄積されたノウハウをフル活用し、お客様の課題解決を行っています。当社は様々な職種でメンバーを募集しています。「オペレーション・エクセレンス」と「らしく働く、らしく生きる」を共に実現するカルチャー・しくみ・働き方にご興味がある方は、アノテーション株式会社 採用サイトをぜひご覧ください。