如何设计CDK项目?

How to design CDK project?

最近开始研究一个 CDK 项目,想了解一下大家对如何构建它的看法。我把我的想法列出来。

将有 2 个单独的包。

  1. ApplicationCommonsPackage
  2. SpecificApplicationCDKPackage(可以是很多这样的包),这些将取决于ApplicationCommonsPackage

ApplicationCommonsPackage 将保存我们所有应用程序的所有通用逻辑(到目前为止已经想到了配置、通用构造、用于创建构造的工厂方法)

后者 (SpecificApplicationCDKPackage) 将保存构造的配置,并将使用 ApplicationCommonsPackage 中的工厂来创建东西。

您如何看待在 ApplicationCommonsPackage 中使用工厂模式?我面临的一个问题是我不能为工厂公开一个带有泛型方法的公共接口(或者不能?)。原因是每个构造都需要非常特定类型的道具,我不能将它们概括为 any 或这样的类型,那样会失去打字稿的好处。所以我的工厂里有像 createLambda(scope: Stack, id: string, props: LambdaProps): Function 这样的功能。我不太喜欢这种结构,我会喜欢将 Function 作为输入并从中确定道具类型的通用函数。像 create<T>(scope: Stack, id: string, props: <U derived from T => some methodology to get this?>): T 这样当我像这样在 SpecificApplicationCDKPackage 中实际使用它时 - this.factory.create<Function>(this, 'SampleLambda', {}) 我得到了 props 参数的所有编译时错误({})

在使用 aws-cdk 时,请务必牢记我们如何将资源收集到 Stack 中。一旦将资源放入 cdk Stack,然后映射到 CloudFormation Stack,在初始生产部署后将其移动到不同的堆栈可能会更复杂。

决定两个资源是否应该在同一个堆栈中的最佳方法是应用模块设计启发式。换句话说,如果资源在堆栈(模块)内的耦合比跨不同堆栈(模块)的耦合更好。

例如,我们经常有一个数据库(例如 RDS)和一些连接到它的服务。与数据库通信时的服务需要其主机名、用户名、密码,并且数据库需要在 AWS 安全组级别允许这些。因此,服务和数据库之间的 引用 数量很高,它们应该存在于单个模块 (CDK Stack) 中。

另一方面,如果我们有 2 个服务,它们通过 http 相互通信,那么一个服务可能只需要知道其他服务的 DNS 名称。在这种情况下,这 2 个服务可能更适合在单独的 Stack 中使用。

我们显然可以拥有辅助库来帮助创建通用结构。但是,请务必记住,在 cdk 中构造的对象映射到 AWS 资源。一旦部署了 CDK 应用程序,看似无害的重构可能会导致资源在后续部署中被替换。