执行失败,因为配置错误:Lambda函数权限无效。

52

我正在使用 AWS Lambda 和 API Gateway 通过 Visual Studio 构建无服务器应用程序。我在 C# 中工作,并使用无服务器应用程序模型 (SAM) 部署我的 API。我在 Visual Studio 中构建代码,然后通过发布到 Lambda 进行部署。这是有效的,但每次我进行新的构建并尝试执行 API 调用时,都会出现以下错误:

由于配置错误,执行失败:Lambda 函数上的权限无效。

经过一些研究,我发现了解决方法(通过 AWS 控制台完成):

解决方法:进入 API Gateway > API 名称 > 资源 > 资源名称 > 方法 > 集成请求 > Lambda 函数,重新选择现有函数,然后使用小勾选符号“保存”它。

现在这对我来说可以工作,但它会中断使用 serverless.template(JSON)自动构建我的 API。有人知道如何在 serverless.template 文件内解决这个问题吗?以便我不需要在控制台上采取措施来解决?这是 serverless.template 文件中一个方法的示例:

{
  "AWSTemplateFormatVersion" : "2010-09-09",
  "Transform" : "AWS::Serverless-2016-10-31",
  "Description" : "An AWS Serverless Application.",

  "Resources" : {

    "Get" : {
      "Type" : "AWS::Serverless::Function",
      "Properties": {
        "VpcConfig":{
          "SecurityGroupIds" : ["sg-111a1476"],
          "SubnetIds" : [ "subnet-3029a769","subnet-5ec0b928"]
        },
        "Handler": "AWSServerlessInSiteDataGw::AWSServerlessInSiteDataGw.Functions::Get",
        "Runtime": "dotnetcore2.0",
        "CodeUri": "",
        "MemorySize": 256,
        "Timeout": 30,
        "Role": null,
        "Policies": [ "AWSLambdaBasicExecutionRole","AWSLambdaVPCAccessExecutionRole","AmazonSSMFullAccess"],
        "Events": {
          "PutResource": {
            "Type": "Api",
            "Properties": {
              "Path": "/",
              "Method": "GET"
            }
          }
        }
      }
    },

非常感谢您的提示。我不知道AWS控制台似乎有这个bug。我能够按照您的建议进行修复,还将其添加到我的terraform代码中。 - atom88
非常感谢您发布这篇文章。我遇到了类似的问题,并且通过这篇文章提供的信息成功解决了它! - atom88
1
太棒了 :) 很高兴能帮到你。 - JamesMatson
就我所知,我之所以出现这个错误是因为在SAM模板的"AWS::Serverless::Function > Properties > Events > Event > path"中设置了错误的路径。 - mojave
14个回答

32

你可能在权限配置方面遇到了问题,这就是为什么API无法调用你的lambda函数。尝试在template.yaml文件中显式地添加invoke权限,以便让apigateway作为一个principal调用你的lambda函数。以下是一个示例:

  ConfigLambdaPermission:
    Type: "AWS::Lambda::Permission"
    DependsOn:
    - MyApiName
    - MyLambdaFunctionName
    Properties:
      Action: lambda:InvokeFunction
      FunctionName: !Ref MyLambdaFunctionName
      Principal: apigateway.amazonaws.com

以下是报告在SAM github 存储库中的问题,这里有一个hello SAM项目的示例

如果您想通过AWS CLI添加权限来测试一些东西,您可能希望使用aws lambda add-permission。请访问官方文档网站了解更多细节。


我之前在指定 SourceArn 属性时定义有误。根据您的回答,我查看了文档并决定将该属性移除,然后问题就得到了解决。我之前使用的是:SourceArn: !Sub arn:aws:execute-api:${AWS::Region}:${AWS::AccountId}:${ApiGateway}/*/POST/*" 不知道具体问题出在哪里。 - Edenshaw
检查我使用控制台链接到 API Gateway 的另一个 Lambda 函数的权限:(如果您转到 Lambda,然后转到 配置->权限->策略语句)我发现 SourceARN 的格式非常不同:arn:aws:execute-api:$AWS_REGION:$AWS_ACCOUNT:$API_ID/authorizers/$SOME_ID 最后一部分(SOME_ID)我不知道它来自哪里或者它的含义是什么,但显然我使用的格式完全不同,也许这就是“Lambda 函数上的无效权限”错误的原因。 - Edenshaw

17

我遇到了类似的问题 - 我删除并重新安装了一个 Lambda 函数。我的 API Gateway 仍然指向旧的 Lambda 函数,所以我需要进入 API Gateway 并更改我的资源方法来修改集成请求设置以指向新的 Lambda 函数(它可能看起来指向正确的 Lambda 函数,但在我的情况下并不是这样)。


2
我也遇到了同样的情况。谢谢你的提示! - Df.fpm
1
很遗憾,这不是一个有效的解决方案,因为这代表着 AWS 存在一个潜在的 bug。此外,如果您有 Cloudformation 模板,则无法在控制台中修改资源。 - Matteo
请注意,这个解决方案对我有效。即使集成似乎指向了正确的 Lambda,你仍然需要重新选择它才能使其工作。然而,这个特定的解决方案在新的 AWS API Gateway 控制台上不起作用。我不得不回到旧的 API 控制台。 - undefined

9
我也遇到了同样的问题,但我是通过Terraform部署的。在另一个用户的建议下,我在API Gateway集成部分重新选择了我的Lambda函数,然后检查了我的Lambda权限中有什么变化。结果我需要在Lambda资源的API Gateway触发器的source_arn部分添加一个“*”来代替阶段名称。不确定SAM如何与Terraform进行比较,但也许您可以更改阶段名称或尝试我尝试过的这个故障排除技术。
我的StackOverflow帖子:AWS API网关和通过terraform部署的Lambda函数--由于Lambda函数的无效权限而执行失败的配置错误

1
我遇到了类似的terraform部署错误,并通过在我的terraform代码中添加额外的权限来修复它。我发现我必须进入lambda函数并查看有效策略以查看差异。 我发现,当策略具有“语句ID”时,它是通过terraform完成的,而当它具有GUID ID时,它是通过控制台完成的。 这帮助我找出要添加的正确策略。 - atom88
1
根据此帖子,这似乎是一个Bug: https://github.com/terraform-providers/terraform-provider-aws/issues/9972 - atom88
1
非常感谢您发布这篇文章。我遇到了类似的问题,并且通过这篇文章提供的信息成功解决了它! - atom88

6
相同错误,解决方案很简单:在API Gateway的集成设置中清除并重新应用“Lambda Function”映射。
我的映射看起来像这样:MyFunction-894AR653OJX:test,“test”是指向我Lambda正确版本的别名。
问题是将Lambda上的ALIAS“test”删除,并在另一个版本上重新创建它(发布后)。似乎API Gateway内部仍然链接到`旧` ALIAS实例。您会期望匹配纯粹是按名称执行的...
额外奖励:因此,通过AWS控制台您无法移动该ALIAS,但是您可以通过AWS CLI使用以下命令执行此操作:
aws lambda --profile <YOUR_PROFILE> update-alias --function-name <FUNCTION_NAME> --name <ALIAS_NAME> --function-version <VERSION_NUMBER>

2

我曾经也遇到过同样的问题。我的解决方法是先将集成方式更改为 mock,即取消 Lambda 集成类型,然后进行一次部署,再将集成类型重新设置为 Lambda。此后,一切都运行得非常顺畅。

希望这能对您有所帮助。


2
面对相同的问题,我发现问题是:API网关无法调用Lambda函数,因为我无法看到Lambda函数的任何CloudWatch日志。
所以首先我查看了API Gateway控制台,在集成请求下,为Lambda函数提供了完整的ARN,然后它开始工作了。
其次,通过CloudFormation。
x-amazon-apigateway-integration:
        credentials:
          Fn::Sub: "${ApiGatewayLambdaRole.Arn}"
        type: "aws"
        uri:
          Fn::Sub: "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${lambda_function.Arn}/invocations"

1
我缺少凭据,你的回答帮助我看清了这一点。谢谢! - rainabba

1
看起来"Execution failed due to configuration error: Invalid permissions on Lambda function"是一个包含多个问题的总结 :D
我使用CloudFormation模板部署了一个堆栈,然后遇到了这个问题。
我曾在AWS::Lambda::Permission段中使用阶段名称作为SourceArn。当我将其更改为*时,AWS更加明确地指出了原因,在我的情况下是AWS::Lambda::Function部分中无效的Handler引用(我使用的是Java,处理程序已经移动了包)。
此外,当我访问我的API GW时,我得到了这个消息。
{
    "message": "Internal server error"
}

只有当我在控制台上发送负载作为资源测试时,才出现了权限错误。

如果我检查API GW的Cloudwatch日志,当我配置时确实提到了真正的原因,即使阶段名称是明确的。

Lambda执行失败,状态码为200,由于客户函数错误而失败:没有名为...的公共方法


1
AWS Lambda 资源权限文档显示了三个访问级别,您可以使用通配符或过滤器进行筛选,/*/*/*,其中 $stage/$method/$path 被记录在文档中。然而,他们的示例和大多数在线示例仅使用两个级别,我一直在尝试使用三个级别,但只得到了 Access Denied 的错误提示。我将级别降低到了两个,Lambda 然后成功创建了触发器。希望这能够帮助某些人避免把电脑砸在墙上。

这个帮我省了好几个小时,看起来就像你说的是两级的:arn:partition:execute-api:region:account-id:api-id/stage/route-key https://docs.aws.amazon.com/apigateway/latest/developerguide/arn-format-reference.html - OrderAndChaos

1

在我的情况下,我遇到了这个错误是因为Lambda函数已经被重命名了。为了确保没有问题,请仔细检查您的配置。

从技术上讲,错误信息是正确的——因为没有函数,所以也就没有权限。当然,一条有用的提示消息将会非常有帮助。


1
我遇到了同样的问题,所以我删除了堆栈然后重新创建,这样就解决了问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接