cloudFormation:api-具有嵌套资源的网关 - 测试工作流程期间出现 500 错误

cloudFormation: api-gateway with nested resources - 500 error during testing workflow

我构建了一个 cloudFormation 模板。它执行一个简单的工作流程:客户端发出请求 -> api 网关处理它并通过代理集成发送到 lambda 函数。 api 网关和 lambda 之间有一个角色。

我的模板包括:

在测试整个工作流程期间,我遇到了一个问题 - api 响应错误 500 内部服务器错误。从日志中我发现消息: Invalid permissions on Lambda function.

我继续测试并发现 当我删除嵌套资源(Segment)并将方法 post 资源(PostMethod)直接连接到根资源(AudienceApi)时,我的工作流程开始工作.

问题:我的模板有什么问题?为什么它不适用于嵌套资源路径?

也许有人查看我的模板并发现错误?

模板:

AWSTemplateFormatVersion: "2010-09-09"
Description: "My API Gateway and Lambda function"

Parameters:
  apiGatewayStageName:
    Type: "String"
    AllowedPattern: "^[a-z0-9]+$"
    Default: "call"

  lambdaFunctionName:
    Type: "String"
    AllowedPattern: "^[a-zA-Z0-9]+[a-zA-Z0-9-]+[a-zA-Z0-9]+$"
    Default: "my-function"

Resources:
  AudienceApi:
    Type: "AWS::ApiGateway::RestApi"
    Properties:
      Name: "my-api"
      Description: "My API"
  Segment:
    Type: 'AWS::ApiGateway::Resource'
    Properties:
      RestApiId: !Ref AudienceApi
      ParentId: !GetAtt
        - AudienceApi
        - RootResourceId
      PathPart: segment
  PostMethod:
    Type: 'AWS::ApiGateway::Method'
    Properties:
      HttpMethod: POST
      #      RequestModels:
      #        application/json: !Ref SegmentationRequestModel
      AuthorizationType: NONE
      Integration:
        IntegrationHttpMethod: POST
        Type: AWS_PROXY
        Uri: !Sub
          - "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambdaArn}/invocations"
          - lambdaArn: !GetAtt "lambdaFunction.Arn"
      ResourceId: !Ref Segment
      RestApiId: !Ref AudienceApi
  lambdaFunction:
    Type: "AWS::Lambda::Function"
    Properties:
      Code:
        ZipFile: |
          def handler(event,context):
            return {
              'body': 'Hello there {0}'.format(event['requestContext']['identity']['sourceIp']),
              'headers': {
                'Content-Type': 'text/plain'
              },
              'statusCode': 200
            }
      Description: "My function"
      FunctionName: !Ref "lambdaFunctionName"
      Handler: "index.handler"
      MemorySize: 128
      Role: !GetAtt "lambdaIAMRole.Arn"
      Runtime: "python2.7"
      Timeout: 10
  lambdaApiGatewayInvoke:
    Type: "AWS::Lambda::Permission"
    Properties:
      Action: "lambda:InvokeFunction"
      FunctionName: !GetAtt "lambdaFunction.Arn"
      Principal: "apigateway.amazonaws.com"
      SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${AudienceApi}/*/POST/"
  lambdaIAMRole:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Action:
              - "sts:AssumeRole"
            Effect: "Allow"
            Principal:
              Service:
                - "lambda.amazonaws.com"
      Policies:
        - PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Action:
                  - "logs:CreateLogGroup"
                  - "logs:CreateLogStream"
                  - "logs:PutLogEvents"
                Effect: "Allow"
                Resource:
                  - !Sub "arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/${lambdaFunctionName}:*"
          PolicyName: "lambda"
  lambdaLogGroup:
    Type: "AWS::Logs::LogGroup"
    Properties:
      LogGroupName: !Sub "/aws/lambda/${lambdaFunctionName}"
      RetentionInDays: 90

根据评论,解决方案是在 SourceArn 中的 POST/ 之后将 * 添加到 ARN:

SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${AudienceApi}/*/POST/*"