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

Posted

技术标签:

【中文标题】如何调试由 CircleCI 编排的 Serverless 生成的 CloudFormation 模板【英文标题】:How to debug CloudFormation templates generated by Serverless orchestrated by CircleCI 【发布时间】:2020-07-11 07:34:14 【问题描述】:

上下文

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

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

它使用无服务器来配置几个 S3 存储桶及其访问策略、几个 IAM 角色和一堆 ApiGateway 方法。该软件包依赖nested stacks 来绕过here 所述的200 个资源限制。

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

问题

在构建的这个步骤中,我不断收到来自 CircleCI 的失败

node_modules/.bin/serverless deploy --verbose --stage develop --region us-east-1 --package ./.serverless

失败的确切性质似乎不一致,即它并不总是在同一个地方失败。在某些时候,资源创建失败,整个过程回滚。以下是日志中运行失败的几个示例,包含 +/- 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
  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]. .

运行 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
  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]. .

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

问题

鉴于以上所有情况,我现在的问题是我该如何调试它?这代表了我(相信)可以使用的所有细节,因为我无法更深入地找到为什么资源创建失败。我已经阅读了一些关于 troubleshooting errors 的内容,但没有什么特别有用的,因为我实际上并没有直接使用 EC2。

4 月 4 日更新

我在调试模板方面做了大量工作。请注意,我通常不使用模板本身,Serverless 会在应用它们之前生成它们并将它们转储到 S3 存储桶中。

这是我采取的一些步骤

    更新到最新版本的无服务器(1.67.0,来自 1.30.3) 核爆现有堆栈 Nuke 相关的 S3 存储桶 更新节点运行时(12.16.1,来自8.10.0) 已下载并检查了包含失败 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)

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

    弄清楚如何将函数拆分到多个 ZIP 中 更改 webpack 配置,使编译后的文件不那么臃肿(我真的不知道这里发生了什么 - webpack 后 1k TypeScript 文件输出为 6.5MB)

【问题讨论】:

您为什么不登录 AWS 控制台,前往云形成部分 --> 选择您的堆栈并单击底部窗格中的事件。这实际上应该告诉您您面临的错误 我同意 Pat Myron 的回答。 @Peter Bailey 您是否尝试查看嵌套堆栈的事件?? 是否也可以包含任何模板、嵌套堆栈事件或 CloudWatch 日志? @PatMyron 是的,我现在不能,但今天/今晚晚些时候。准备好后我会发表另一条评论 @PatMyron 这是我在额外日志记录方面可用的。我将其与问题分开,因为我不想将未混淆的数据作为问题历史的一部分。 gist.github.com/baileyp/f4df7058e0b8982ba6bdba7061a6db7f 【参考方案1】:

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

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

AWS Lambda limits 也可能,我建议尝试things like this

检查是否还有任何 CloudWatch 日志

【讨论】:

谢谢你。我已经进行了一些更新,但似乎仍然在努力解决同样的问题。任何进一步的见解将不胜感激! 哦,忘了说,我的发现已经记录在上面的原始问题中了

以上是关于如何调试由 CircleCI 编排的 Serverless 生成的 CloudFormation 模板的主要内容,如果未能解决你的问题,请参考以下文章

如何在 circleci 作业中执行“docker run”命令

Circleci:如何根据 git release 进行部署(发布一个标签)

我们如何有条件地运行 CircleCI 工作流程?

如何在CircleCI 2.0上配置顺序工作流?

如何只在 GitHub 主分支上运行 CircleCI?

仅当同一仓库中的文件添加了新条目时,如何在 github 仓库中运行 CircleCI 作业?