使用 Serverless Framework 绕过 AWS CloudFormation 模板的 500 个资源限制
AWS 为使用 AWS CloudFormation 部署无服务器应用程序提供了强大的基础架构。然而,在开发大型无服务器项目时,资源限制并不罕见。解决此挑战的一种方法是将 CloudFormation 堆栈拆分为更小、更易于管理的单元。AWS 建议使用嵌套堆栈来突破 500 个资源的限制。在本文中,我们将探讨如何使用 Serverless Framework 和一个名为 `<plugin_name>` 的插件来实现这一点serverless-plugin-split-stacks。我们还将讨论一些技巧和窍门,以使该过程更加顺畅。
嵌套堆栈是一种安全的方式,既能解决资源限制问题,又能保留单堆栈的优势。单堆栈的主要优势在于可以一次性部署和回滚所有资源。由于嵌套堆栈依赖于其父堆栈,因此如果其中一个嵌套堆栈部署失败,父堆栈将回滚到之前的状态。嵌套堆栈还共享输出变量(例如 ID 或 ARN)。我们保持了堆栈的原子性行为。
先决条件
在深入细节之前,请确保您已准备好以下事项:
- AWS账户
- 已安装 Node.js 和 npm。
- Serverless Framework 已安装(
npm install -g serverless) - 一个 Serverless Framework 项目搭建
使用 serverless-plugin-split-stacks 拆分堆栈
安装
首先,您需要安装serverless-plugin-split-stacks插件。请导航至您的 Serverless 项目目录并运行以下命令:
npm install serverless-plugin-split-stacks --save-dev
配置
在您的serverless.ts(或serverless.yml)文件中,将插件添加到以下plugins部分:
plugins: ['serverless-plugin-split-stacks'],
并在以下部分进行配置custom:
custom: {
// ...
splitStacks: {
perFunction: false,
perType: false,
perGroupFunction: true,
nestedStackCount: 10,
},
}
perFunction将其设置为 truetrue会将每个 AWS Lambda 函数的堆栈拆分。将其设置为 falsefalse则可保持堆栈结构易于管理。perType:如果要根据资源类型(例如,DynamoDB 表、S3 存储桶)拆分堆栈,请将其设置为true。perGroupFunction:此选项设置为true,它会根据函数分组(lambda 及其所有相关资源,例如 IAM 角色)将堆栈平均拆分。nestedStackCount:如果未指定则禁用;它控制并行部署的资源数量。stackConcurrency: number:如果未指定则禁用;它控制并行部署的堆栈数量。
重命名现有 Lambda 函数
这里有个棘手的问题。该插件无法处理现有资源。虽然您可以使用自定义迁移强制将现有资源迁移到新堆栈,force: true但这会删除该资源并重新创建它。这可能会导致 CloudFormation 冲突或 IAM 问题。因此,不建议在生产环境中使用此功能。
别担心,有办法解决。
如果您已有 Lambda 函数,则需要将其重命名以符合新的结构。最简单的方法是在函数名后添加下划线后缀_。例如,如果您有一个名为 `<Lambda_name>` 的 Lambda 函数myFunction,则可以将其重命名为 `<Lambda_name>` myFunction_。当然,您可以使用任何其他后缀,但下划线后缀是一个很好的约定,因为它易于阅读且视觉上更简洁。
就这样,你的 lambda 函数无需删除就会被移动到新的堆栈中。
部署堆栈
首次部署包含这些更改的 Serverless 项目时,请确保将该disableRollback参数设置为 `true` false。这样,如果在部署过程中出现问题,AWS 将不会自动回滚更改。以下是设置方法:
sls deploy --disableRollback false
初始部署完成后,出于安全考虑,建议将其恢复disableRollback到true初始状态。这样可以确保在部署失败的情况下,堆栈能够回滚到之前的状态。
例子
让我们用一个简单的例子来说明这些步骤。考虑一个包含三个函数的无服务器服务:userFunction,,orderFunction和paymentFunction。
-
安装
serverless-plugin-split-stacks插件。 -
配置您的
serverless.ts文件:
service: my-serverless-app
frameworkVersion: '>=2.50.0'
plugins:
- serverless-plugin-split-stacks
provider:
name: aws
runtime: nodejs18.x
custom:
splitStacks:
perFunction: false
perType: false
perGroupFunction: true
nestedStackCount: 10
functions:
userFunction:
handler: userFunction.handler
orderFunction:
handler: orderFunction.handler
paymentFunction:
handler: paymentFunction.handler
-
如有必要,请重命名现有 Lambda 函数。
-
按照上述说明部署堆栈。
💭 局限性
达到资源限制可能表明您的应用程序过于复杂。最好重新审视一下您的架构,看看是否可以简化或重新组织它。服务规模越小,维护和管理起来就越容易。
🧠 结论
通过使用拆分 AWS CloudFormation 堆栈serverless-plugin-split-stacks,您可以突破 500 个资源的限制,并更有效地管理您的无服务器应用程序。这种方法不仅使您的基础架构更具可扩展性,而且随着无服务器项目的增长,还能简化其维护工作。
然而,子堆栈也有其局限性,并非可以无限扩展。它们的资源限制与主堆栈相同,嵌套堆栈越多,堆栈部署所需的时间就越长。
需要拆分技术栈表明您的应用程序变得过于复杂,您应该重新审视其架构。一种改变拆分方式的方法是为每个解耦的业务实体创建一个技术栈。或者,微服务架构可能并不适合您的用例:您可以考虑例如六边形架构。