1
0
はじめての記事投稿
Qiita Engineer Festa20242024年7月17日まで開催中!

AWS SAMでAPIGateway+LambdaをopenAPIで書いてデプロイしたらテストでInternal server errorになったので、解消した話

Last updated at Posted at 2024-06-18

APIGatewayとLambdaのtemplate.ymlを分割したら、Internal server errorになった

AWS SAMを使用して、template.ymlファイルを次のように分割し、APIGatewayの定義にopenAPI(swagger?)を利用することで、APIGatewayとLambdaを紐づけていました。

※ 筆者は大元のtemplate.ymlにAPIGatewayの定義をしています。

フォルダ構成はざっくりこんな感じ。

.
├── template.yml
├── package.json
├── tsconfig.json
└── functions
    └──helloWorld
        ├──index.ts (handler)
        └──lambda-template.yml

以下、大元のtemplate.ymlと、Lambda定義のtemplateの中身です。

template.yml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31

Resources:
  # functionsディレクトリに保存したlambda-template.yml(後述)で定義したLambdaを読み込む
  HelloWorldFunction:
    Type: AWS::Serverless::Application
    Properties:
      Location: functions/helloWorld/lambda-template.yml # 適宜正しいディレクトリパスに置き換えてください

  API:
    Type: AWS::Serverless::Api
    Properties:
      Name: hello-world-api
      StageName: dev
      DefinitionBody:
        openapi: 3.0.1
        info:
          title: hello-world-api
          version: "2021-10-01"
        paths:
          /hello-world:
            get:
              x-amazon-apigateway-integration:
                uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:HelloWorldFunction/invocations
                httpMethod: POST
                type: aws_proxy

Lambdaのtemplate.yml

lambda-template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: HelloWorldFunction
      Handler: index.handler
      Runtime: nodejs18.x

AWSコンソールからAPIGatewayのテストを実行すると…image.png

で、最終行を見てみると

Execution failed due to configuration error: Invalid permissions on Lambda function

結論(解決方法)

次のように修正

template.yml
AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Application
    Properties:
      Location: functions/helloWorld/lambda-template.yml
      Parameters: # APIの論理IDをLambdaの定義に渡す
        API: !Ref API
        
  API:
    Type: AWS::Serverless::Api
    Properties:
      Name: hello-world-api
      StageName: dev
      DefinitionBody:
        openapi: 3.0.1
        info:
          title: hello-world-api
          version: "2021-10-01"
        paths:
          /hello-world:
            get:
              x-amazon-apigateway-integration:
                uri: !Sub arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:function:HelloWorldFunction/invocations
                httpMethod: POST
                type: aws_proxy
lambda-template.yml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Parameters: # 大元のtemplate.ymlのParametersと紐づけ
  API:
    Type: String

Resources:
  HelloWorldFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: HelloWorldFunction
      Handler: index.handler
      Runtime: nodejs18.x

  LambdaPermission: # LambdaにAPIからの呼び出しを許可する「リソースベースのポリシー」を追加
    Type: AWS::Lambda::Permission
    Properties:
      FunctionName: !GetAtt HelloWorldFunction.Arn
      Action: lambda:InvokeFunction
      Principal: apigateway.amazonaws.com
      SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${API}/*/GET/hello-world

AWS::Lambda::Permissionについてはこちらを見てください。

これでデプロイ⇒APIGatewayでテストを実行する。
image.png

こんにちは!しました。

原因

原因はLambdaの設定の「リソースベースのポリシー」が空だったことにあります。

image.png

ここに、APIGatewayからの呼び出しを許可するポリシーをくっ付けてやる必要があるのですが、その記述がtemplate.ymlにありませんでした。

そもそも論

APIGatewayと同じtemplate.ymlにLambdaを定義することで、わざわざAWS::Lambda::Permissionの記述をする必要はありません。

例えばこちらのような感じ。

どうやら、SAMの内部的な処理で良しなにやってくれるみたいです。
こちらの記事も同じ事象みたいなので、掲載します。

てか、本記事よりもリンクの記事の方が正しく書いていただいているので、私と同じ事象になった方は是非参照されたし。

最後に

何か補足や間違いがあれば、随時更新しようと思います。
それ以外の感想や、「役に立った」等、何でも良いので、是非コメント頂けると嬉しいです!

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