手动删除SAM CloudFormation堆栈中的函数后找不到函数

时间:2019-05-16 00:46:22

标签: amazon-web-services aws-lambda amazon-cloudformation aws-sam

我正在使用sam deploy来部署lambda函数和API网关。它可以正常工作,但是在我通过AWS控制台手动删除了lambda函数之后却无法正常工作。我遇到以下错误:

"ResourceStatusReason": "Function not found: 
  arn:aws:lambda:ap-southeast-2:286334053171:function:polaroid (Service: 
  AWSLambdaInternal; Status Code: 404; Error Code: ResourceNotFoundException;
  Request ID: b431cbfc-7772-11e9-8022-1b92fa2cfa9e)

删除lambda并进行刷新部署的正确方法是什么?如果发生这种情况,如何强制SAM创建缺少的lambda函数?

模板yaml中的lambda如下:

...
Resources:
  PolaroidFunction:
    Type: AWS::Serverless::Function 
    Properties:
      FunctionName: test
      CodeUri: ./lambdas
      Handler: lib/index.fun
      Runtime: nodejs8.10
      Events:
        polaroid:
          Type: Api 
          Properties:
            Path: /test
            Method: post
...

3 个答案:

答案 0 :(得分:3)

我遇到了类似的问题。就我而言,我在尝试重置 TRIM_HORIZON 以使其重新处理 DynamoDB 流中的旧事件时删除了 Lambda 作为实验。

我找到了一个更简单的解决方案:

进入 CloudFormation 控制台并删除已部署的堆栈。

sam deploy 之后再次正常工作。

答案 1 :(得分:0)

我想您已经学会了一种绝妙的方式,即永远不要手动删除由SAM或CloudFormation管理的资源。

通常,如果您只想更改功能,则只需调用sam buildsam deploy,就会部署新版本。无需删除任何内容。如果您需要更高级的工作流程,则需要阅读博客文章。没有正确的方法可以做到这一点。

但是,要解决您的紧迫问题,这是您可以做的。 1

首先,您需要获取生成的AWS CloudFormation模板:

▶ aws cloudformation get-template --stack-name HelloWorld \
    --template-stage Processed --query TemplateBody | cfn-flip -y > processed.yml

接下来,您需要注释掉刚创建的processed.yml文件中的函数,并注释掉引用该函数的Lambda权限。还要保存原始processed.yml文件的备份。

此外,如果可能的话,通过从AWS控制台获取构建时计算的实际值CloudFormation来更新对它的任何其他模板引用。例如,如果您有对${HelloWorldFunction.Arn}的引用,则可能必须使用arn:aws:lambda:ap-southeast-2:123456789012:function:HelloWorld-HelloWorldFunction-1NJGQI7GEAUM1这样的字符串来更新模板中的那些引用。

接下来,使用AWS CloudFormation命令验证模板:

▶ aws cloudformation validate-template --template-body file://processed.yml
{
    "CapabilitiesReason": "The following resource(s) require capabilities: [AWS::IAM::Role]",                                                                         
    "Description": "sam-app\nSample SAM Template for sam-app\n",
    "Parameters": [],
    "Capabilities": [
        "CAPABILITY_IAM"
    ]
}

接下来,您将使用此修改后的模板更新堆栈。通过这种方式更新堆栈,您可以从CloudFormation的角度使模板和实际状态恢复同步:

▶ aws cloudformation update-stack --template-body file://processed.yml --stack-name HelloWorld --capabilities CAPABILITY_IAM                        
{
    "StackId": "arn:aws:cloudformation:ap-southeast-2:885164491973:stack/HelloWorld/af2c6810-7884-11e9-9bb3-068b1a8e1450"
}

如果一切顺利,您的堆栈将进入UPDATE_COMPLETE状态。太好了!

最后,取消注释掉您注释掉的所有资源,并恢复所有原始值。然后第二次更新堆栈,您的堆栈应恢复到原始状态。

另请参阅:


1 请注意,我使用SAM随附的默认HelloWorld Python 2.7示例测试了此方法。

答案 2 :(得分:0)

如果您想避免删除堆栈并重新部署它,或者避免对齐 CloudFormation 模板文件,也许您可​​以将 AWS 中的资源与模板文件对齐。

这意味着,如果您删除了最初从模板文件创建的某个 Lambda(例如),只需在 AWS(GUI 或 aws cli)中手动创建相同的 Lambda。 现在再次运行 'sam deploy' - 你应该对齐了。

现在从模板文件中删除 Lambda 定义并再次部署 - 应该删除 Lambda 并且 CloudFormation 将对齐。