问题描述
我正在尝试通过Api网关触发器调用lambda ReplySms
这是我的template.yaml:
Resources:
SmsRole:
Type: AWS::IAM::Role
Properties:
RoleName: !Sub ${Environment}-${Application}-role
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Action:
- sts:AssumeRole
Principal:
Service:
- lambda.amazonaws.com
- apigateway.amazonaws.com
Effect: Allow
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
- arn:aws:iam::aws:policy/SecretsManagerReadWrite
SmsApi:
Type: AWS::Serverless::Api
Tags:
username: !Ref UserName
Application: !Ref Application
Properties:
Name: !Sub ${Environment}-sms-service
StageName: !Ref Environment
MethodSettings:
- LoggingLevel: INFO
DataTraceEnabled: false
ResourcePath: "/*"
HttpMethod: "*"
ReplySms:
Type: AWS::Serverless::Function
Properties:
ReservedConcurrentExecutions: 100
FunctionName: !Sub ${Environment}-${Application}-reply-sms
CodeUri: target
Handler: replySms.handler
Runtime: nodejs12.x
MemorySize: 128
Timeout: 30
Role: !GetAtt SmsRole.Arn
ReplySmsResource:
Type: AWS::ApiGateway::Resource
Properties:
RestApiId: !Ref SmsApi
ParentId: !GetAtt SmsApi.RootResourceId
PathPart: replysms
EmptyModel:
Type: AWS::ApiGateway::Model
Properties:
RestApiId: !Ref SmsApi
ContentType: application/xml
Description: Empty schema to map lambda response
Name: EmptyModel
Schema: {}
ReplyMethod:
Type: AWS::ApiGateway::Method
Properties:
AuthorizationType: NONE
HttpMethod: POST
Integration:
Type: AWS
Credentials: !GetAtt SmsRole.Arn
IntegrationHttpMethod: POST
Uri: !Sub 'arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ReplySms.Arn}/invocations'
PassthroughBehavior: WHEN_NO_TEMPLATES
RequestTemplates:
application/x-www-form-urlencoded: |
#set($httpPost = $input.path('$').split("&"))
{
#foreach( $kvPair in $httpPost )
#set($kvTokenised = $kvPair.split("="))
#if( $kvTokenised.size() > 1 )
"$kvTokenised[0]" : "$kvTokenised[1]"#if( $foreach.hasNext ),#end
#else
"$kvTokenised[0]" : ""#if( $foreach.hasNext ),#end
#end
#end
}
IntegrationResponses:
- StatusCode: 200
ResponseTemplates: {"application/xml": "$input.path('$')"}
MethodResponses:
- StatusCode: 200
ResponseModels:
application/xml: !Ref EmptyModel
ResourceId: !Ref ReplySmsResource
RestApiId: !Ref SmsApi
InvokeReplySmsLambda:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
FunctionName: !GetAtt ReplySms.Arn
Principal: apigateway.amazonaws.com
SourceArn: !Sub "arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${SmsApi}/*/POST/replysms"
# SmsApiDeployment:
# Type: "AWS::ApiGateway::Deployment"
# DependsOn:
# - ReplyMethod
# Properties:
# RestApiId: !Ref SmsApi
# StageName: !Ref Environment
Outputs:
ApiResourceUrl:
Value: !Sub https://${SmsApi}.execute-api.${AWS::Region}.amazonaws.com/${Environment}/
自3天以来我一直在进行此操作,但仍然无法弄清楚出了什么问题。从其他答案中我发现我需要添加一个权限资源,因此我添加了InvokeReplySmsLambda,它应该可以修复错误。
但仍然得到Execution Failed due to configuration error: Invalid permissions on Lambda function
(66c44450-af76-4c93-accd-xxxxxxxxxxxx) Extended Request Id: RKHI5FEMIAMFc-w=
(66c44450-af76-4c93-accd-b659d3c8f2ee) Verifying Usage Plan for request: 66c44450-af76-4c93-accd-b659d3c8f2ee. API Key: API Stage: dhrcl2tzqa/sandBox
(66c44450-af76-4c93-accd-b659d3c8f2ee) API Key authorized because method 'POST /replysms' does not require API Key. Request will not contribute to throttle or quota limits
(66c44450-af76-4c93-accd-b659d3c8f2ee) Usage Plan check succeeded for API Key and API Stage dhrcl2tzqa/sandBox
(66c44450-af76-4c93-accd-b659d3c8f2ee) Starting execution for request: 66c44450-af76-4c93-accd-b659d3c8f2ee
(66c44450-af76-4c93-accd-b659d3c8f2ee) HTTP Method: POST,Resource Path: /replysms
(66c44450-af76-4c93-accd-b659d3c8f2ee) Execution Failed due to configuration error: Invalid permissions on Lambda function
(66c44450-af76-4c93-accd-b659d3c8f2ee) Method completed with status: 500
任何帮助将不胜感激。
解决方法
首先
删除您的InvokeReplySmsLambda
AWS::Lambda::Permission
资源。您将不需要它,因为SAM CLI将创建一个策略,该策略可以隐式调用Lambda(docs reference)。
是否需要隐式创建的角色的Arn始终为:FunctionNameRole.Arn
(在Yaml中使用类似!GetAtt ReplySmsRole.Arn
的用法)。您可以在aws控制台的堆栈详细信息(cloudformation)或“角色”部分(IAM)的资源选项卡之一中确认该值。
第二,
将您的Lambda函数编辑为
-
删除
Role
属性 -
包括一个
Policies
属性以及您想要的其他策略(SecretsManagerReadWrite)。ReplySms: Type: AWS::Serverless::Function Properties: ReservedConcurrentExecutions: 100 FunctionName: !Sub ${Environment}-${Application}-reply-sms CodeUri: target Handler: replySms.handler Runtime: nodejs12.x MemorySize: 128 Timeout: 30 Policies: - SecretsManagerReadWrite
注释:
我还将提到您可以使用Events类型的EventSource(API)属性并合并AWS::ApiGateway::Method
资源。一个例子可以在这里找到:
https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-resource-function--examples
hths!