在 SAM CloudFormation 堆栈中手动删除函数后找不到函数
Function not found after manually deleting a function in a SAM CloudFormation stack
我正在使用 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
...
我想您已经学到了绝不能手动删除由 SAM 或 CloudFormation 管理的资源的艰难方法。
一般来说,如果你只是想改变功能,你可以直接调用sam build
和sam deploy
,新版本就会被部署。无需删除任何内容。如果您需要更高级的工作流程,则需要阅读博客文章。没有一种正确的方法可以做到这一点。
然而,要解决您眼前的问题,您可以执行以下操作。1
首先,您需要获取生成的AWS CloudFormation模板:
▶ aws cloudformation get-template --stack-name HelloWorld \
--template-stage Processed --query TemplateBody | cfn-flip -y > processed.yml
接下来需要注释掉刚刚创建的processed.yml
文件中的函数,同时注释掉引用它的Lambda Permissions。还要保存原始 processed.yml
文件的备份。
此外,如果可能,请使用构建堆栈时 CloudFormation 计算的实际值更新对它的任何其他模板引用,方法是从 AWS 控制台获取它们。例如,如果您有对 ${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 状态。太棒了!
最后,将所有被注释掉的资源取消注释,全部恢复原值。然后第二次更新堆栈,你的堆栈应该恢复到原来的状态。
另请参阅:
- AWS 知识库,2016 年、2019 年,How do I update an AWS CloudFormation stack that's failing because of a resource that I manually deleted?。
- 有关 cfn-flip 实用程序的更多信息,如果您没有的话。
1 请注意,我使用 SAM 附带的默认 HelloWorld Python 2.7 示例测试了此方法。
我遇到了类似的问题。在我的例子中,我在尝试重置 TRIM_HORIZON
以使其重新处理 DynamoDB 流中的旧事件时删除了 Lambda 作为实验。
我找到了一个更简单的解决方案:
进入 CloudFormation 控制台并删除已部署的堆栈。
sam deploy
之后再次正常工作。
如果你想避免删除堆栈并重新部署它,或者避免对齐 CloudFormation 模板文件,也许你可以只将 AWS 中的资源对齐到模板文件中。
这意味着,如果您删除了最初从模板文件创建的某个 Lambda(例如),只需在 AWS(GUI 或 aws cli)中手动创建相同的 Lambda。
现在又 运行 'sam deploy' - 你应该对齐了。
现在从模板文件中删除 Lambda 定义并再次部署 - Lambda 应该被删除并且 CloudFormation 将对齐。
我正在使用 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
...
我想您已经学到了绝不能手动删除由 SAM 或 CloudFormation 管理的资源的艰难方法。
一般来说,如果你只是想改变功能,你可以直接调用sam build
和sam deploy
,新版本就会被部署。无需删除任何内容。如果您需要更高级的工作流程,则需要阅读博客文章。没有一种正确的方法可以做到这一点。
然而,要解决您眼前的问题,您可以执行以下操作。1
首先,您需要获取生成的AWS CloudFormation模板:
▶ aws cloudformation get-template --stack-name HelloWorld \
--template-stage Processed --query TemplateBody | cfn-flip -y > processed.yml
接下来需要注释掉刚刚创建的processed.yml
文件中的函数,同时注释掉引用它的Lambda Permissions。还要保存原始 processed.yml
文件的备份。
此外,如果可能,请使用构建堆栈时 CloudFormation 计算的实际值更新对它的任何其他模板引用,方法是从 AWS 控制台获取它们。例如,如果您有对 ${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 状态。太棒了!
最后,将所有被注释掉的资源取消注释,全部恢复原值。然后第二次更新堆栈,你的堆栈应该恢复到原来的状态。
另请参阅:
- AWS 知识库,2016 年、2019 年,How do I update an AWS CloudFormation stack that's failing because of a resource that I manually deleted?。
- 有关 cfn-flip 实用程序的更多信息,如果您没有的话。
1 请注意,我使用 SAM 附带的默认 HelloWorld Python 2.7 示例测试了此方法。
我遇到了类似的问题。在我的例子中,我在尝试重置 TRIM_HORIZON
以使其重新处理 DynamoDB 流中的旧事件时删除了 Lambda 作为实验。
我找到了一个更简单的解决方案:
进入 CloudFormation 控制台并删除已部署的堆栈。
sam deploy
之后再次正常工作。
如果你想避免删除堆栈并重新部署它,或者避免对齐 CloudFormation 模板文件,也许你可以只将 AWS 中的资源对齐到模板文件中。
这意味着,如果您删除了最初从模板文件创建的某个 Lambda(例如),只需在 AWS(GUI 或 aws cli)中手动创建相同的 Lambda。 现在又 运行 'sam deploy' - 你应该对齐了。
现在从模板文件中删除 Lambda 定义并再次部署 - Lambda 应该被删除并且 CloudFormation 将对齐。