【发布时间】:2020-09-12 07:09:50
【问题描述】:
我有一个 CloudFormation stack template,它创建了一个 API 网关资源,其中方法是 Type: LAMBDA_PROXY。它最初适用于访问根域,例如 https://28af295f439b5f0aef7c7805864ba3981f282e1e.guacchain.com/ - 但是当我尝试访问 https://28af295f439b5f0aef7c7805864ba3981f282e1e.guacchain.com/about 时,网络请求会返回状态代码 500 和响应 {"message": "Internal server error"}
生成的 Lambda 函数将此作为其基于资源的策略:
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "stack-28af295f439b5f0aef7c7805864ba3981f282e1e-lambdaApiGatewayInvoke-128TRSSUE8WDQ",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-1:378688096774:function:lambda-28af295f439b5f0aef7c7805864ba3981f282e1e",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:us-east-1:378688096774:bccwb0kvvd/*/*/*"
}
}
}
]
}
当转到 API Gateway 集成请求页面并简单地编辑 Lambda 函数字段(剪切现有值然后将其粘贴回来,然后点击复选标记)时,我会看到这个“添加权限”弹出窗口:
单击“确定”然后刷新 Lambda 控制台页面后,其 Resource-base Policy 会更新以包含两个看似重复的语句(唯一的区别是 Sid 字段):
{
"Version": "2012-10-17",
"Id": "default",
"Statement": [
{
"Sid": "stack-28af295f439b5f0aef7c7805864ba3981f282e1e-lambdaApiGatewayInvoke-128TRSSUE8WDQ",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-1:378688096774:function:lambda-28af295f439b5f0aef7c7805864ba3981f282e1e",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:us-east-1:378688096774:bccwb0kvvd/*/*/*"
}
}
},
{
"Sid": "d6d795d4-8461-4774-bd6e-ae8d8ea3bcee",
"Effect": "Allow",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Action": "lambda:InvokeFunction",
"Resource": "arn:aws:lambda:us-east-1:378688096774:function:lambda-28af295f439b5f0aef7c7805864ba3981f282e1e",
"Condition": {
"ArnLike": {
"AWS:SourceArn": "arn:aws:execute-api:us-east-1:378688096774:bccwb0kvvd/*/*/*"
}
}
}
]
}
部署 API 网关并等待大约一分钟后,https://28af295f439b5f0aef7c7805864ba3981f282e1e.guacchain.com/about 终于可以访问了。所以我的问题是,原始的基于 Lambda 资源的策略阻止除/ 之外的所有请求在域上被访问有什么不足?
我想指出的一个细微之处是,在剪切 Lambda 函数名称并将其粘贴到集成请求页面后,它不会显示为自动完成选项,而其他选项则会显示。
这是我在 CloudFormation 堆栈中定义的 lambdaIAMRole:
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
Lambda 函数资源将 Role: !GetAtt lambdaIAMRole.Arn 作为其 Properties 字段的一部分。
【问题讨论】:
-
尝试
StringLike而不是ArnLike。检查stackoverflow.com/a/56145538/643500 -
ArnLike字段仅出现在 Lambda 控制台页面上 - 我如何通过 CloudFormation 模板对其进行编辑? -
应该没有区别。这是你经常观察的事情,还是一次性的事情?
-
我检查了你的模板。我在那里看到一个错误,可以解释为什么您的 {proxy+} 不起作用。在你的
apiGatewayLambdaResourceMethod中你应该有IntegrationHttpMethod: POST,而不是 GET。因为您使用AWS_PROXY,所以它必须始终是 POST。当您在控制台中执行此操作时,它将正确设置为 POST。 -
那个。做过。它。 @Marcin,如果您将其发布为我会接受的答案。这感觉就像似曾相识。
标签: amazon-web-services aws-lambda amazon-cloudformation amazon-iam