如何调试由 CircleCI 编排的 Serverless 生成的 CloudFormation 模板

Pet*_*ley 5 amazon-web-services aws-cloudformation circleci serverless infrastructure-as-code

语境

我觉得我需要在这里提供很多背景信息才能理解问题的全部范围,所以如果这有点长或最终提供了太多信息,请提前道歉,只是想避免很多人跟随尽我所能提出问题和澄清请求。

我有一个技术交接的项目。它曾经在不同所有者的不同 AWS 账户下进行生产。我正在尝试在我控制的 AWS 账户中重新启动它,但其中一个软件包给我带来了一些问题。

它使用 Serverless 来配置几个 S3 存储桶及其访问策略、几个 IAM 角色和一堆 ApiGateway 方法。该包依赖嵌套堆栈来绕过 200 个资源限制,如此处所述

最后,CircleCI 连接的 IAM 用户已AdministratorAccess附加策略。

问题

在构建的这一步中,我不断收到 CircleCI 的失败消息

node_modules/.bin/serverless deploy --verbose --stage develop --region us-east-1 --package ./.serverless
Run Code Online (Sandbox Code Playgroud)

故障的确切性质似乎不一致,即它并不总是在同一位置发生故障。在某些时候,资源无法创建,整个过程会回滚。以下是日志中运行失败的几个示例,其中包含 +/- 5 行,后面是 Serverless 报告的实际错误

运行1

CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethod001VarOptions
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethod002VarOptions
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethod003VarOptions
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethod004VarOptions
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethod006Options
CloudFormation - CREATE_FAILED - AWS::CloudFormation::Stack - FuncAbcNestedStack
CloudFormation - CREATE_FAILED - AWS::CloudFormation::Stack - FuncDefNestedStack
CloudFormation - CREATE_FAILED - AWS::CloudFormation::Stack - FuncGhiNestedStack
CloudFormation - UPDATE_ROLLBACK_IN_PROGRESS - AWS::CloudFormation::Stack - org-package-develop
CloudFormation - UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - org-package-develop
CloudFormation - DELETE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethod006Options
Run Code Online (Sandbox Code Playgroud)
  Serverless Error ---------------------------------------

  An error occurred: FuncAbcNestedStack - Embedded stack arn:aws:cloudformation:us-east-1:ACCOUNT_ID:stack/org-package-develop-FuncAbcNestedStack/RESOURCE-ID-001 was not successfully created: The following resource(s) failed to create: [AbcLambdaFunction]. .
Run Code Online (Sandbox Code Playgroud)

运行2

CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethod001VarOptions
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethod002VarOptions
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethod005VarOptions
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethod006Options
CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethod004VarOptions
CloudFormation - CREATE_FAILED - AWS::CloudFormation::Stack - FuncDefNestedStack
CloudFormation - CREATE_FAILED - AWS::CloudFormation::Stack - FuncGhiNestedStack
CloudFormation - CREATE_FAILED - AWS::CloudFormation::Stack - FuncAbcNestedStack
CloudFormation - UPDATE_ROLLBACK_IN_PROGRESS - AWS::CloudFormation::Stack - org-package-develop
CloudFormation - UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - org-package-develop
CloudFormation - DELETE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethod001VarOptions
Run Code Online (Sandbox Code Playgroud)
  Serverless Error ---------------------------------------

  An error occurred: FuncDefNestedStack - Embedded stack arn:aws:cloudformation:us-east-1:ACCOUNT_ID:stack/org-package-develop-FuncDefNestedStack/RESOURCE-ID-002 was not successfully created: The following resource(s) failed to create: [DefLambdaFunction]. .
Run Code Online (Sandbox Code Playgroud)

注意:上述日志中的所有唯一标识符已被新标识符替换/混淆,新标识符在两个日志中都是唯一的,而不是每个日志,即FuncAbcNestedStack出现在两个日志中,因为它与配置中的资源完全相同。

问题

鉴于上述所有内容,我现在的问题是如何调试它?这代表了我(相信)可以使用的所有细节,因为我无法更深入地了解资源创建失败的原因。我读过一些有关错误排查的内容,但没有什么特别有帮助的,因为我实际上并没有直接使用 EC2。

4 月 4 日更新

我已经做了大量的工作来尝试调试模板。请注意,我通常不使用模板本身,无服务器会生成它们并在应用它们之前将它们转储到 S3 存储桶中。

这是我采取的一些步骤

  1. 更新到最新版本的 Serverless(1.67.0,来自1.30.3
  2. 摧毁现有堆栈
  3. Nuked相关S3存储桶
  4. 更新了节点运行时(12.16.1,来自8.10.0
  5. 下载并检查了包含失败 lambda 的 CFN 模板 - 没有报告任何问题

我仍然得到相同的结果。当我重新运行构建并检查 CloudFormation 事件日志时,我确实看到堆栈无法创建,因为其中的 Lambda 函数无法创建。该函数没有什么特别之处(其他 Lambda 在运行早期成功创建),除了它是 API 中每个其他函数的授权者这一事实之外,这可能很重要,也可能不重要。我仍然无法找到有关lambda 为何无法创建的更多详细信息。

4 月 6 日更新

好的,现在我了解了 CloudFormation 控制台的工作原理,现在我认为这最底层的错误消息

Unzipped size must be smaller than 262144000 bytes (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: 0507722d-46e7-4340-bc68-fdba1ed469d6)
Run Code Online (Sandbox Code Playgroud)

查看此嵌套堆栈的 CFN 模板本身,我现在明白发生了什么。每个lamba都有自己的堆栈,整个包中的每个堆栈都被编译成一个ZIP文件,其大小最终大约为270MB或比上面指定的限制大20MB。从这一点来看,我似乎有两条可能的前进道路

  1. 弄清楚如何将功能拆分到多个 ZIP 中
  2. 更改 webpack 配置,以便编译后的文件不那么臃肿(我真的不知道这里发生了什么 - 一个 1k TypeScript 文件在 webpack 后变成了 6.5MB)

Pat*_*ron 2

您需要查看嵌套堆栈本身。和资源在嵌套堆栈中应该比在父堆栈中具有更详细的故障堆栈事件AbcLambdaFunctionDefLambdaFunction您可能需要修复嵌套堆栈模板中的AbcLambdaFunctionDefLambdaFunction,因为不一致可能只是由于哪个资源首先失败并开始回滚造成的

如果这些模板运行已经有一段时间了,那么Lambda 运行时可能已被弃用。CloudFormation Linter应该能够检查您的模板是否存在此问题以及更多可能性

AWS Lambda 限制也可能存在,我建议尝试这样的事情

检查是否还有 CloudWatch 日志