Lambda 调用权限与 API 网关权限冲突
Permissions for Lambda invocation conflicts with API Gateway permissions
我已将一个应用程序部署到 Lambda,我正在使用 API 网关将 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 组权限不能很好地协同工作。
- 我需要允许 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
PS:此模板甚至不需要 Serverless::Api
部分。
我已将一个应用程序部署到 Lambda,我正在使用 API 网关将 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 组权限不能很好地协同工作。
- 我需要允许 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
PS:此模板甚至不需要 Serverless::Api
部分。