typescript - 如何在 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 或某種方式來等待堆疊完成?
答案#1
如果你試圖引用像將會生成的 CloudFront 發行 Id 這樣的「動態」事物,我可能會嘗試使用兩個不同的堆疊,並讓一個依賴另一個。
我不太確定我是否正確理解你的使用情境。但也許可以查看包含如何對某些東西進行參數化並在不同堆疊間傳遞資訊的 Core 套件說明文件。
https://docs.aws.amazon.com/cdk/api/latest/docs/core-readme.html
編輯:你可以這樣做:
var s1 = new stackOne();
var s2 = new stackTwo().addDependency(s1);
這篇部落格文章對我很有幫助: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,然後使用 CLI 查詢 AWS API,無論是手動操作還是如果我們在自動化更多後續操作的 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. '
});
}
}
在建立堆疊後,在管道/命令列介面中,使用以下命令來取得變數的值:
aws cloudformation describe-stacks --stack-name CloudFrontStack --query "Stacks[0].Outputs[?OutputKey=='CloudFront-DistributionId'].OutputValue"這將產生在堆疊建立後創建的分發 ID。
