简体   繁体   English

AWS CDK 多个应用程序

[英]AWS CDK multiple Apps

Would it be possible to have two CDK Apps in the same project, something like this:是否可以在同一个项目中有两个 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()

And deploy them?并部署它们? Synchronously/Asynchronously?同步/异步?

Would it be possible to reference some resources from one app in the other one?是否可以在另一个应用程序中引用一些资源?

Yes you can have multiple applications in a CDK project, but there are some serious caveats.是的,您可以在一个 CDK 项目中拥有多个应用程序,但有一些严重的警告。

  1. A CDK process can only synth/deploy one app at a time. CDK 进程一次只能合成/部署一个应用程序。

  2. They cannot be defined in the same file.它们不能在同一个文件中定义。

  3. They cannot directly reference each other's resources.他们不能直接引用彼此的资源。

To put this in perspective, each app is functionally isolated from each other and it is roughly equivalent to having two separate CDK projects just sharing the same codebase, so the use cases for this are limited.从这个角度来看,每个应用程序在功能上是相互隔离的,大致相当于有两个单独的 CDK 项目共享相同的代码库,因此用例有限。

The only way for them to share resources is either to extract it to an additional common app that must be deployed first, or for you to store the ARN of that resource in something (eg, Parameter Store), and load it at run time.他们共享资源的唯一方法是将其提取到必须首先部署的其他通用应用程序中,或者让您将该资源的 ARN 存储在某个东西(例如 Parameter Store)中,并在运行时加载它。 You cannot assume that the resource will exist as one of the apps may not have been deployed yet, and if you import the resource into your Stack directly, you've defeated the whole point of splitting them apart.您不能假设该资源将存在,因为其中一个应用程序可能尚未部署,并且如果您将资源直接导入您的堆栈,那么您就已经打败了将它们分开的全部意义。

That is to say, this is ok:也就是说,这样就ok了:

stack1.lambda: 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

But if it's critical to stack1 that a resource from stack2 exists, or you want to import a stack2 resource into stack1, then you either need to do a third split of all the common resources: common-resources.app.py , or there's no point splitting them.但是,如果存在来自 stack2 的资源对 stack1 至关重要,或者您想将 stack2 资源导入到 stack1 中,那么您需要对所有公共资源进行第三次拆分: common-resources.app.py ,或者没有点拆分它们。


We do this a lot in our projects, with one app creating a CodePipeline that automatically deploys the other app.我们在我们的项目中经常这样做,一个应用程序创建了一个自动部署另一个应用程序的 CodePipeline。 However, we only do this because we prefer the pipeline lives next to the code it is deploying and it would be equally valid to extract it into an entirely new project.但是,我们这样做只是因为我们更喜欢管道存在于它正在部署的代码旁边,并且将它提取到一个全新的项目中同样有效。


If you want to do this, you need to do:如果你想这样做,你需要这样做:

app1.py:应用程序1.py:

from aws_cdk import core

from stack1 import Stack1

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

app2.py:应用程序2.py:

from aws_cdk import core

from stack2 import Stack2

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

You then deploy this by running in parallel or sequentially:然后通过并行或顺序运行来部署它:

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

Having re-read your question, the short answer is no.重新阅读您的问题后,简短的回答是否定的。 In testing this, I found that CDK would only create the second app defined.在对此进行测试时,我发现 CDK 只会创建定义的第二个应用程序。

You can, however, deploy multiple-stack applications:但是,您可以部署多堆栈应用程序:

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

It's also possible to reference resources from one stack in another, by using core.CfnOutput and core.Fn.importValue:也可以通过使用 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 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

Under the hood, this uses CloudFormation's ability to export outputs and import them in other stacks.在后台,这使用了 CloudFormation 导出输出并将它们导入其他堆栈的能力。 Effectively your multiple stack CDK app will create nested CloudFormation stacks.实际上,您的多堆栈 CDK 应用程序将创建嵌套的 CloudFormation 堆栈。

In terms of deployments, CDK creates a CloudFormation change set and deploys it, so all changes will be deployed on cdk deploy .在部署方面,CDK 创建了一个 CloudFormation 更改集并进行部署,因此所有更改都将部署在cdk deploy上。 From your perspective, it'll be synchronous, but there may be some asynchronous API calls happening under the hood through CloudFormation.从您的角度来看,它将是同步的,但可能会通过 CloudFormation 在后台发生一些异步 API 调用。

Yes , you can do pretty much the exact thing that you gave as an example in your question: have 2 apps and synthesize them into 2 separate folders.的,您几乎可以做您在问题中作为示例给出的完全相同的事情:拥有 2 个应用程序并将它们合成到 2 个单独的文件夹中。 You do that by overriding outdir prop for each app, otherwise they would override each other's compiled files.您可以通过覆盖每个应用程序的 outdir 属性来做到这一点,否则它们会覆盖彼此的编译文件。 See more complete example at the end.最后查看更完整的示例。

A few caveats though!不过有一些注意事项!

  • As of the time of this writing, this is most likely unsupported.截至撰写本文时,这很可能不受支持。 In the docs of the outdir property it says:outdir属性的文档中,它说:

    You should never need to set this value.您永远不需要设置此值。

    This property is intended for internal and testing use.此属性供内部和测试使用。

    • So take it or leave it on your own risk:)因此,请自行承担风险:)
  • Calling cdk synth on this project will indeed create 2 folders with the right files but the command fails with ENOENT: no such file or directory, open 'cdk.out/manifest.json' .在这个项目上调用cdk synth确实会创建 2 个包含正确文件的文件夹,但命令失败并显示ENOENT: no such file or directory, open 'cdk.out/manifest.json' The mentioned folder cdk.out is created too, it's just empty.提到的文件夹 cdk.out 也被创建,它只是空的。 So I guess the CDK team doesn't account for anyone using this approach.所以我猜CDK 团队没有考虑任何使用这种方法的人。 I don't know CDK internals well enough to be 100% sure but from a brief glance into the compiled templates, the output looks ok and should probably work.我不太了解 CDK 内部结构,无法 100% 确定,但简要浏览编译的模板,output 看起来不错,应该可以工作。

  • You are limited in what you can share between the apps.您可以在应用程序之间共享的内容受到限制。 Note that when you instantiate a stack, the first argument is an app.请注意,当您实例化堆栈时,第一个参数是应用程序。 Therefore, for the second app you need a new instantiation.因此,对于第二个应用程序,您需要一个新的实例化。

You can deploy each app separately with --app flag, eg cdk deploy --app cdk.out.dev您可以使用 --app 标志单独部署每个应用程序,例如cdk deploy --app cdk.out.dev

Full example here:完整的例子在这里:

#!/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();

Now, you didn't tell us what were you trying to achieve.现在,你没有告诉我们你想要达到什么目标。 My goal when first looking into this was to have a separate app for each environment.我第一次研究这个时的目标是为每个环境都有一个单独的应用程序。 CDK offers Stage construct for this purpose, docs here . CDK 为此目的提供了 Stage 构造, 这里的文档

An abstract application modeling unit consisting of Stacks that should be deployed together.由应一起部署的堆栈组成的抽象应用程序建模单元。

You can then instantiate (stage) multiple times to model multiple copies of your application which should be be deployed to different environments.然后,您可以多次实例化(暂存)到 model 应部署到不同环境的应用程序的多个副本。

Maybe that's what you were really looking for?也许这就是你真正想要的?

Based on your comments - mainly seeking to do parrallel deployments from your local - you don't need multiple apps.根据您的评论 - 主要是寻求从您的本地进行并行部署 - 您不需要多个应用程序。

Just open a new terminal shell and start deploying again, using stack names to define which stack you are currently deploying:只需打开一个新终端 shell 并再次开始部署,使用堆栈名称来定义您当前正在部署的堆栈:

**Shell 1**
cdk deploy StackName1

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

and they will both run simultaneously.它们将同时运行。 They have no interaction with each other, and if they depend on each others resources to be deployed in a certain order this will simply be a recipe for disaster.它们彼此之间没有交互,如果它们依赖于彼此的资源以某种顺序进行部署,这将只会导致灾难。

but if all you are looking for is speed of deployment, then yeah.但是,如果您要寻找的只是部署速度,那么是的。 This will do the trick just fine.这会很好地解决问题。

If this is a common action however, you'd be best advised to set up a CodePipeline with one stage having two CodeDeploy actions to deploy your stacks from the synthed templates (or two codebuilds to do the same thing using cdk deploy)但是,如果这是一个常见操作,最好建议您设置一个具有两个 CodeDeploy 操作的阶段的 CodePipeline,以从合成模板部署您的堆栈(或使用 cdk deploy 执行相同操作的两个代码构建)

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

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