在 AWS CDK 中执行代码之前如何等待堆栈完成?
How to wait stack to complete before executing code in AWS CDK?
我正在尝试 AWS CDK,但在尝试执行依赖于堆栈完成的代码块时卡住了。
这是我当前的代码:
class Application extends cdk.Construct {
constructor(scope: cdk.Construct, id: string) {
super(scope, id);
const webStack = new WebsiteStack(app, `website-stack-${id}`, { stage: id })
const buildStack = new CodeBuildStack(app, `codebuild-stack-${id}`, { stage:id, bucket: webStack.websiteBucket, distribution: webStack.websiteDistribution });
this.generateBuildParameter(id, webStack, buildStack)
}
generateBuildParameter(id: string, webStack: WebsiteStack, buildStack: CodeBuildStack) {
const buildParam = {
projectName: buildStack.buildProject.projectName,
sourceVersion: id,
environmentVariablesOverride: [
{ name: "STAGE", value: id, type: "PLAINTEXT" },
{ name: "WEBSITE_BUCKET", value: webStack.websiteBucket.bucketName, type: "PLAINTEXT" },
{ name: "CLOUDFRONT_DISTRIBUTION_ID", value: webStack.websiteDistribution.distributionId, "type": "PLAINTEXT" }
],
buildspecOverride: "./buildspec.yml"
}
fse.outputJson(`./cdk.out/build-parameters/build-${id}.json`, buildParam, (err: Error) => {
if (err) {
throw err
};
console.log(`build parameter has been created in "../cdk.out/build-parameters/build-${id}.json"`);
})
}
}
我只是想生成一个依赖于 buildStack
的 json 文件。但是,它似乎没有等待堆栈完成。
这是我当前的输出:
{
"projectName":"${Token[TOKEN.41]}",
"sourceVersion":"master",
"environmentVariablesOverride":[{"name":"STAGE","value":"master","type":"PLAINTEXT"},{"name":"WEBSITE_BUCKET","value":"${Token[TOKEN.17]}","type":"PLAINTEXT"},{"name":"CLOUDFRONT_DISTRIBUTION_ID","value":"${Token[TOKEN.26]}","type":"PLAINTEXT"}],
"buildspecOverride":"./buildspec.yml"
}
AWS CDK 是否支持 Promise 或某种等待堆栈完成的方式?
如果您尝试引用 'dynamic' 诸如将生成的 CloudFront 分发 ID 之类的内容,我可能会尝试使用 2 个不同的堆栈,并且一个依赖另一个。
我不确定我是否正确理解了您的用例。但也许可以查看核心包自述文件,其中包含如何参数化某些内容以及如何跨堆栈传递信息。
https://docs.aws.amazon.com/cdk/api/latest/docs/core-readme.html
编辑:你可以这样做:
var s1 = new stackOne();
var s2 = new stackTwo().addDependency(s1);
这篇博客 post 对我很有帮助:https://lanwen.ru/posts/aws-cdk-edge-lambda/
编辑:一些栈间共享资源的实际例子。 StackA 创建一个 CloudFront 分配(分配的 ID 是动态的)
StackB 需要 CloudFront 分配 ID 来设置警报。
// stackA
export class CloudFrontStack extends cdk.Stack {
readonly distribution: cf.CloudFrontWebDistribution;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
distribution = new cf.CloudFrontWebDistribution(this, 'my-cloud-front-dist', {//props here...} );
}
}
// stack B
export class AlarmStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, cloudfrontDistributionId: string, props?: cdk.StackProps) {
super(scope, id, props);
new alarm.Alarm()// alarm definition, need ID of CF Distribution here.
}
}
//index.ts where everything is linked:
const app = new cdk.App();
const stack1= new CloudFrontStack(app, 'CFStack1');
const stack2= new AlarmStack(app, 'AlarmStack', stack1.distribution.distributionId);
// you can even specify that stack2 cannot be created unless stack1 succeeds.
stack2.addDependency(stack1);
EDIT2: 对于在CDK之外构建堆栈后创建的资源,我能想到的最简单的方法是定义CfnOutputs然后查询AWS api 使用 CLI,手动或在 CI/CD 管道中,如果我们之后要自动化更多的事情。
示例 2:使用前面的示例,我们将定义一个名为 CloudFront-DistributioId 的输出并使用 CLI 查询它。
// stackA
export class CloudFrontStack extends cdk.Stack {
readonly distribution: cf.CloudFrontWebDistribution;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
distribution = new cf.CloudFrontWebDistribution(this, 'my-cloud-front-dist', {//props here...} );
// define a cloud formation output so we can query later
new CfnOutput(this, 'CloudFront-DistributionId', {
exportName: 'CloudFront-DistributionId',
value: cloudFrontDistribution.distributionId,
description: 'The dynamic value created by aws of our CloudFront distribution id. '
});
}
}
创建栈后,在pipeline/cli中,使用如下命令获取变量的值:
aws cloudformation describe-stacks --stack-name CloudFrontStack --query "Stacks[0].Outputs[?OutputKey=='CloudFront-DistributionId'].OutputValue"
这将生成在构建堆栈后创建的分发 ID。
我正在尝试 AWS CDK,但在尝试执行依赖于堆栈完成的代码块时卡住了。
这是我当前的代码:
class Application extends cdk.Construct {
constructor(scope: cdk.Construct, id: string) {
super(scope, id);
const webStack = new WebsiteStack(app, `website-stack-${id}`, { stage: id })
const buildStack = new CodeBuildStack(app, `codebuild-stack-${id}`, { stage:id, bucket: webStack.websiteBucket, distribution: webStack.websiteDistribution });
this.generateBuildParameter(id, webStack, buildStack)
}
generateBuildParameter(id: string, webStack: WebsiteStack, buildStack: CodeBuildStack) {
const buildParam = {
projectName: buildStack.buildProject.projectName,
sourceVersion: id,
environmentVariablesOverride: [
{ name: "STAGE", value: id, type: "PLAINTEXT" },
{ name: "WEBSITE_BUCKET", value: webStack.websiteBucket.bucketName, type: "PLAINTEXT" },
{ name: "CLOUDFRONT_DISTRIBUTION_ID", value: webStack.websiteDistribution.distributionId, "type": "PLAINTEXT" }
],
buildspecOverride: "./buildspec.yml"
}
fse.outputJson(`./cdk.out/build-parameters/build-${id}.json`, buildParam, (err: Error) => {
if (err) {
throw err
};
console.log(`build parameter has been created in "../cdk.out/build-parameters/build-${id}.json"`);
})
}
}
我只是想生成一个依赖于 buildStack
的 json 文件。但是,它似乎没有等待堆栈完成。
这是我当前的输出:
{
"projectName":"${Token[TOKEN.41]}",
"sourceVersion":"master",
"environmentVariablesOverride":[{"name":"STAGE","value":"master","type":"PLAINTEXT"},{"name":"WEBSITE_BUCKET","value":"${Token[TOKEN.17]}","type":"PLAINTEXT"},{"name":"CLOUDFRONT_DISTRIBUTION_ID","value":"${Token[TOKEN.26]}","type":"PLAINTEXT"}],
"buildspecOverride":"./buildspec.yml"
}
AWS CDK 是否支持 Promise 或某种等待堆栈完成的方式?
如果您尝试引用 'dynamic' 诸如将生成的 CloudFront 分发 ID 之类的内容,我可能会尝试使用 2 个不同的堆栈,并且一个依赖另一个。
我不确定我是否正确理解了您的用例。但也许可以查看核心包自述文件,其中包含如何参数化某些内容以及如何跨堆栈传递信息。
https://docs.aws.amazon.com/cdk/api/latest/docs/core-readme.html
编辑:你可以这样做:
var s1 = new stackOne();
var s2 = new stackTwo().addDependency(s1);
这篇博客 post 对我很有帮助:https://lanwen.ru/posts/aws-cdk-edge-lambda/
编辑:一些栈间共享资源的实际例子。 StackA 创建一个 CloudFront 分配(分配的 ID 是动态的)
StackB 需要 CloudFront 分配 ID 来设置警报。
// stackA
export class CloudFrontStack extends cdk.Stack {
readonly distribution: cf.CloudFrontWebDistribution;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
distribution = new cf.CloudFrontWebDistribution(this, 'my-cloud-front-dist', {//props here...} );
}
}
// stack B
export class AlarmStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, cloudfrontDistributionId: string, props?: cdk.StackProps) {
super(scope, id, props);
new alarm.Alarm()// alarm definition, need ID of CF Distribution here.
}
}
//index.ts where everything is linked:
const app = new cdk.App();
const stack1= new CloudFrontStack(app, 'CFStack1');
const stack2= new AlarmStack(app, 'AlarmStack', stack1.distribution.distributionId);
// you can even specify that stack2 cannot be created unless stack1 succeeds.
stack2.addDependency(stack1);
EDIT2: 对于在CDK之外构建堆栈后创建的资源,我能想到的最简单的方法是定义CfnOutputs然后查询AWS api 使用 CLI,手动或在 CI/CD 管道中,如果我们之后要自动化更多的事情。
示例 2:使用前面的示例,我们将定义一个名为 CloudFront-DistributioId 的输出并使用 CLI 查询它。
// stackA
export class CloudFrontStack extends cdk.Stack {
readonly distribution: cf.CloudFrontWebDistribution;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
distribution = new cf.CloudFrontWebDistribution(this, 'my-cloud-front-dist', {//props here...} );
// define a cloud formation output so we can query later
new CfnOutput(this, 'CloudFront-DistributionId', {
exportName: 'CloudFront-DistributionId',
value: cloudFrontDistribution.distributionId,
description: 'The dynamic value created by aws of our CloudFront distribution id. '
});
}
}
创建栈后,在pipeline/cli中,使用如下命令获取变量的值:
aws cloudformation describe-stacks --stack-name CloudFrontStack --query "Stacks[0].Outputs[?OutputKey=='CloudFront-DistributionId'].OutputValue"
这将生成在构建堆栈后创建的分发 ID。