Amazon web services Lambda调用的权限与API网关权限冲突

Amazon web services Lambda调用的权限与API网关权限冲突,amazon-web-services,aws-lambda,aws-api-gateway,serverless,Amazon Web Services,Aws Lambda,Aws Api Gateway,Serverless,我已经在Lambda上部署了一个应用程序,我正在使用API网关将HTTP请求转发到该应用程序 我的问题是,API网关似乎没有将不属于应用程序的基本URL的请求转发 换句话说,当对HTTP请求时,Lambda处理程序中的代码将被执行https://blabblahblah.execute-api.us-west-2.amazonaws.com/Prod/。但是,对https://blabblahblah.execute-api.us-west-2.amazonaws.com/Prod/pong抛出

我已经在Lambda上部署了一个应用程序,我正在使用API网关将HTTP请求转发到该应用程序

我的问题是,API网关似乎没有将不属于应用程序的基本URL的请求转发

换句话说,当对
HTTP请求时,Lambda处理程序中的代码将被执行https://blabblahblah.execute-api.us-west-2.amazonaws.com/Prod/
。但是,对
https://blabblahblah.execute-api.us-west-2.amazonaws.com/Prod/pong
抛出一个500,但不执行任何代码。我的处理程序中有一些日志记录语句,它们不会记录非基本URL请求的任何内容

我已将问题缩小为权限问题

我有两套权限不能很好地协同工作

  • 我需要允许API网关调用我的lambda函数
  • lambda函数需要能够调用自身
  • 我认为这两个权限都可以正常工作,但任何不针对基本URL的HTTP请求都会在API网关中抛出500(即,我没有看到请求的Cloudwatch日志条目,但响应是500)

    我想这意味着我的SAM模板中一定有一些错误

    Resources:
      IAMRole:
        Type: AWS::IAM::Role
        Properties:
          AssumeRolePolicyDocument:
            Statement:
              - Action: ['sts:AssumeRole']
                Effect: Allow
                Principal:
                  Service: [lambda.amazonaws.com]
            Version: 2012-10-17
          ManagedPolicyArns:
            - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    
      MyFunction:
        Type: AWS::Serverless::Function
        Properties:
          Handler: lambda.handler
          Role: !GetAtt IAMRole.Arn
          Runtime: ruby2.5
          CodeUri: "./src/"
          MemorySize: 512
          Timeout: 30
          Events:
            MyAppApi:
                Type: Api
                Properties:
                    Path: /
                    Method: ANY
                    RestApiId: !Ref MyAppAPI
      MyAppAPI:
        Type: AWS::Serverless::Api
        Properties:
          Name: MyAppAPI
          StageName: Prod
          DefinitionBody:
            swagger: '2.0'
            basePath: '/'
            info:
              title: !Ref AWS::StackName
            paths:
              /{proxy+}:
                x-amazon-apigateway-any-method:
                  responses: {}
                  x-amazon-apigateway-integration:
                    uri:
                      !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations'
                    passthroughBehavior: "when_no_match"
                    httpMethod: POST
                    type: "aws_proxy"
              /:
                post:
                  responses: {}
                  x-amazon-apigateway-integration:
                    uri:
                      !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations'
                    passthroughBehavior: "when_no_match"
                    httpMethod: POST
                    type: "aws_proxy"
      ConfigLambdaPermission:
        Type: "AWS::Lambda::Permission"
        DependsOn:
        - MyFunction
        Properties:
          Action: lambda:InvokeFunction
          FunctionName: !Ref MyFunction
          Principal: apigateway.amazonaws.com
      ConfigLambdaPermission:
        Type: "AWS::Lambda::Permission"
        DependsOn:
        - MyFunction
        Properties:
          Action: lambda:InvokeFunction
          FunctionName: !Ref MyFunction
          Principal: !GetAtt IAMRole.Arn
    
    Outputs:
      MyFunction:
        Description: Lambda Function for interacting with Slack
        Value:
          Fn::GetAtt:
          - MyFunction
          - Arn
      MyAppAppUrl:
        Description: App endpoint URL
        Value: !Sub "https://${MyAppAPI}.execute-api.${AWS::Region}.amazonaws.com/"
    

    你知道如何让事情正常运行吗?

    是的,你需要添加其他资源和事件触发器。您的lambda权限在上述模板中没有任何用处。这就是它对我的作用

    AWSTemplateFormatVersion: "2010-09-09"
    Transform: AWS::Serverless-2016-10-31
    Resources:
      IAMRole:
        Type: AWS::IAM::Role
        Properties:
          AssumeRolePolicyDocument:
            Statement:
              - Action: ['sts:AssumeRole']
                Effect: Allow
                Principal:
                  Service: [lambda.amazonaws.com]
            Version: 2012-10-17
          ManagedPolicyArns:
            - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    
      MyFunction:
        Type: AWS::Serverless::Function
        Properties:
          Handler: roleTest.roleTest
          Role: !GetAtt IAMRole.Arn
          Runtime: nodejs8.10
          CodeUri: s3://apicfn/roleTest.zip
          MemorySize: 512
          Timeout: 30
          Events:
            MyAppApi1:
                Type: Api
                Properties:
                    Path: /
                    Method: ANY
            MyAppApi2:
                Type: Api
                Properties:
                    Path: /{proxy+}
                    Method: ANY
    Outputs:
      MyFunction:
        Description: Lambda Function for interacting with Slack
        Value:
          Fn::GetAtt:
          - MyFunction
          - Arn
    

    注:此模板甚至不需要
    Serverless::Api
    部分。

    谢谢!这解决了问题!添加单独的事件完全有意义。出于好奇,为什么在没有IAM角色的情况下代理工作得很好?根“\”的工作方式是函数定义中指定的,因此它隐式地创建了权限。另一个资源(proxy+)是restapi定义的一部分&需要明确的权限。上述解决方案更简单。
    Resources:
      IAMRole:
        Type: AWS::IAM::Role
        Properties:
          AssumeRolePolicyDocument:
            Statement:
              - Action: ['sts:AssumeRole']
                Effect: Allow
                Principal:
                  Service: [lambda.amazonaws.com]
            Version: 2012-10-17
          ManagedPolicyArns:
            - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
    
      MyFunction:
        Type: AWS::Serverless::Function
        Properties:
          Handler: lambda.handler
          Role: !GetAtt IAMRole.Arn
          Runtime: ruby2.5
          CodeUri: "./src/"
          MemorySize: 512
          Timeout: 30
          Events:
            MyAppApi:
                Type: Api
                Properties:
                    Path: /
                    Method: ANY
                    RestApiId: !Ref MyAppAPI
      MyAppAPI:
        Type: AWS::Serverless::Api
        Properties:
          Name: MyAppAPI
          StageName: Prod
          DefinitionBody:
            swagger: '2.0'
            basePath: '/'
            info:
              title: !Ref AWS::StackName
            paths:
              /{proxy+}:
                x-amazon-apigateway-any-method:
                  responses: {}
                  x-amazon-apigateway-integration:
                    uri:
                      !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations'
                    passthroughBehavior: "when_no_match"
                    httpMethod: POST
                    type: "aws_proxy"
              /:
                post:
                  responses: {}
                  x-amazon-apigateway-integration:
                    uri:
                      !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${MyFunction.Arn}/invocations'
                    passthroughBehavior: "when_no_match"
                    httpMethod: POST
                    type: "aws_proxy"
      ConfigLambdaPermission:
        Type: "AWS::Lambda::Permission"
        DependsOn:
        - MyFunction
        Properties:
          Action: lambda:InvokeFunction
          FunctionName: !Ref MyFunction
          Principal: apigateway.amazonaws.com
      ConfigLambdaPermission:
        Type: "AWS::Lambda::Permission"
        DependsOn:
        - MyFunction
        Properties:
          Action: lambda:InvokeFunction
          FunctionName: !Ref MyFunction
          Principal: !GetAtt IAMRole.Arn
    
    Outputs:
      MyFunction:
        Description: Lambda Function for interacting with Slack
        Value:
          Fn::GetAtt:
          - MyFunction
          - Arn
      MyAppAppUrl:
        Description: App endpoint URL
        Value: !Sub "https://${MyAppAPI}.execute-api.${AWS::Region}.amazonaws.com/"