【问题标题】:Permissions for Lambda invocation conflicts with API Gateway permissionsLambda 调用权限与 API Gateway 权限冲突
【发布时间】:2019-02-08 16:50:02
【问题描述】:

我有一个应用程序部署到 Lambda,我正在使用 API Gateway 将 HTTP 请求转发到应用程序。

我的问题是,API 网关似乎没有将请求转发到应用的基本 URL。

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

我已将问题缩小到权限问题。

我有 2 组权限不能很好地协同工作。

  1. 我需要允许 API Gateway 调用我的 lambda 函数
  2. 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/"

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

【问题讨论】:

    标签: amazon-web-services aws-lambda aws-api-gateway serverless


    【解决方案1】:

    是的,您需要添加其他资源以及事件触发器。而且你的 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
    

    PS:这个模板甚至不需要Serverless::Api 部分。

    【讨论】:

    • 谢谢!这解决了问题!添加单独的事件完全有意义。只是出于好奇,为什么代理的东西在没有 IAM 角色的情况下工作得很好?
    • 根 '\' 按照函数定义中指定的方式工作,因此它隐式创建了权限。另一个资源(proxy+)是 REST API 定义的一部分,并且需要明确的权限。上述解决方案更简单。
    猜你喜欢
    • 2017-08-20
    • 2018-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-27
    • 1970-01-01
    • 2017-02-15
    • 2023-03-15
    相关资源
    最近更新 更多