繁体   English   中英

AWS CDK 多个应用程序

[英]AWS CDK multiple Apps

是否可以在同一个项目中有两个 CDK 应用程序,如下所示:

from aws_cdk import core

from stack1 import Stack1
from stack2 import Stack2

app1 = core.App()
Stack1(app1, "CDK1")
app1.synth()

app2 = core.App()
Stack2(app2, "CDK2")
app2.synth()

并部署它们? 同步/异步?

是否可以在另一个应用程序中引用一些资源?

是的,您可以在一个 CDK 项目中拥有多个应用程序,但有一些严重的警告。

  1. CDK 进程一次只能合成/部署一个应用程序。

  2. 它们不能在同一个文件中定义。

  3. 他们不能直接引用彼此的资源。

从这个角度来看,每个应用程序在功能上是相互隔离的,大致相当于有两个单独的 CDK 项目共享相同的代码库,因此用例有限。

他们共享资源的唯一方法是将其提取到必须首先部署的其他通用应用程序中,或者让您将该资源的 ARN 存储在某个东西(例如 Parameter Store)中,并在运行时加载它。 您不能假设该资源将存在,因为其中一个应用程序可能尚未部署,并且如果您将资源直接导入您的堆栈,那么您就已经打败了将它们分开的全部意义。

也就是说,这样就ok了:

stack1.lambda:

    from ssm_parameter_store import SSMParameterStore

    store = SSMParameterStore(prefix='/Prod')
    ssn_arn = store['stack2.sns']
    if !ssn_arn
        // Doesn't matter
        return
    try:
        sns.publish(ssn_arn, 'something')
    except:
        // Doesn't matter

但是,如果存在来自 stack2 的资源对 stack1 至关重要,或者您想将 stack2 资源导入到 stack1 中,那么您需要对所有公共资源进行第三次拆分: common-resources.app.py ,或者没有点拆分它们。


我们在我们的项目中经常这样做,一个应用程序创建了一个自动部署另一个应用程序的 CodePipeline。 但是,我们这样做只是因为我们更喜欢管道存在于它正在部署的代码旁边,并且将它提取到一个全新的项目中同样有效。


如果你想这样做,你需要这样做:

应用程序1.py:

from aws_cdk import core

from stack1 import Stack1

app1 = core.App()
Stack1(app1, "CDK1")
app1.synth()

应用程序2.py:

from aws_cdk import core

from stack2 import Stack2

app2 = core.App()
Stack2(app2, "CDK2")
app2.synth()

然后通过并行或顺序运行来部署它:

  • cdk deploy --app "python app1.py"
  • cdk deploy --app "python app2.py"

重新阅读您的问题后,简短的回答是否定的。 在对此进行测试时,我发现 CDK 只会创建定义的第二个应用程序。

但是,您可以部署多堆栈应用程序:

https://docs.aws.amazon.com/cdk/latest/guide/stack_how_to_create_multiple_stacks.html

也可以通过使用 core.CfnOutput 和 core.Fn.importValue 从一个堆栈中引用另一个堆栈中的资源:

https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.core/CfnOutput.html https://docs.aws.amazon.com/cdk/api/latest/python/aws_cdk.core /Fn.html

在后台,这使用了 CloudFormation 导出输出并将它们导入其他堆栈的能力。 实际上,您的多堆栈 CDK 应用程序将创建嵌套的 CloudFormation 堆栈。

在部署方面,CDK 创建了一个 CloudFormation 更改集并进行部署,因此所有更改都将部署在cdk deploy上。 从您的角度来看,它将是同步的,但可能会通过 CloudFormation 在后台发生一些异步 API 调用。

的,您几乎可以做您在问题中作为示例给出的完全相同的事情:拥有 2 个应用程序并将它们合成到 2 个单独的文件夹中。 您可以通过覆盖每个应用程序的 outdir 属性来做到这一点,否则它们会覆盖彼此的编译文件。 最后查看更完整的示例。

不过有一些注意事项!

  • 截至撰写本文时,这很可能不受支持。 outdir属性的文档中,它说:

    您永远不需要设置此值。

    此属性供内部和测试使用。

    • 因此,请自行承担风险:)
  • 在这个项目上调用cdk synth确实会创建 2 个包含正确文件的文件夹,但命令失败并显示ENOENT: no such file or directory, open 'cdk.out/manifest.json' 提到的文件夹 cdk.out 也被创建,它只是空的。 所以我猜CDK 团队没有考虑任何使用这种方法的人。 我不太了解 CDK 内部结构,无法 100% 确定,但简要浏览编译的模板,output 看起来不错,应该可以工作。

  • 您可以在应用程序之间共享的内容受到限制。 请注意,当您实例化堆栈时,第一个参数是应用程序。 因此,对于第二个应用程序,您需要一个新的实例化。

您可以使用 --app 标志单独部署每个应用程序,例如cdk deploy --app cdk.out.dev

完整的例子在这里:

#!/usr/bin/env node
import "source-map-support/register";
import * as cdk from "aws-cdk-lib";
import { EventInfrastructureStack } from "../lib/stacks/event-infrastructure-stack";

const devApp = new cdk.App({
  outdir: "cdk.out.dev",
});
new EventInfrastructureStack(devApp, "EventInfrastructureStack", {
  env: {
    account: "account1",
    region: "eu-west-1",
  },
});

const prodApp = new cdk.App({
  outdir: "cdk.out.prod",
});
new EventInfrastructureStack(prodApp, "EventInfrastructureStack", {
  env: {
    account: "acount2",
    region: "eu-west-1",
  },
});

devApp.synth();
prodApp.synth();

现在,你没有告诉我们你想要达到什么目标。 我第一次研究这个时的目标是为每个环境都有一个单独的应用程序。 CDK 为此目的提供了 Stage 构造, 这里的文档

由应一起部署的堆栈组成的抽象应用程序建模单元。

然后,您可以多次实例化(暂存)到 model 应部署到不同环境的应用程序的多个副本。

也许这就是你真正想要的?

根据您的评论 - 主要是寻求从您的本地进行并行部署 - 您不需要多个应用程序。

只需打开一个新终端 shell 并再次开始部署,使用堆栈名称来定义您当前正在部署的堆栈:

**Shell 1**
cdk deploy StackName1

> Open a new terminal window
**Shell 2**
cdk deploy OtherStackName

它们将同时运行。 它们彼此之间没有交互,如果它们依赖于彼此的资源以某种顺序进行部署,这将只会导致灾难。

但是,如果您要寻找的只是部署速度,那么是的。 这会很好地解决问题。

但是,如果这是一个常见操作,最好建议您设置一个具有两个 CodeDeploy 操作的阶段的 CodePipeline,以从合成模板部署您的堆栈(或使用 cdk deploy 执行相同操作的两个代码构建)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM