在 AWS CDK 中为多个堆栈创建可预测的堆栈名称
Create predicatable stack names for multiple stacks in AWS CDK
在由 multiple stacks that I would like to deploy to multiple environments 组成的 AWS CDK 应用程序中执行 npx cdk synth
时如何获取 "nice" 堆栈名称?
#!/usr/bin/env node
import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';
import * as lambda from '@aws-cdk/aws-lambda';
class PersistenceStack extends cdk.Stack {
public readonly bucket: s3.Bucket;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
this.bucket = new s3.Bucket(this, 'bucket');
}
}
interface ApplicationStackProps extends cdk.StackProps {
bucket: s3.Bucket;
}
class ApplicationStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props: ApplicationStackProps) {
super(scope, id, props);
const myLambda = new lambda.Function(this, 'my-lambda', {
runtime: lambda.Runtime.NODEJS_12_X,
code: new lambda.AssetCode('my-lambda'),
handler: 'index.handler'
});
props.bucket.grantReadWrite(myLambda);
}
}
class MyApp extends cdk.Construct {
constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) {
super(scope, id);
const persistenceStack = new PersistenceStack(this, 'persistence-stack', {
...props,
description: 'persistence stack',
stackName: `${id}-persistence-stack`,
});
const applicationStack = new ApplicationStack(this, 'application-stack', {
...props,
description: 'application stack',
stackName: `${id}-application-stack`,
bucket: persistenceStack.bucket,
});
applicationStack.addDependency(persistenceStack);
}
}
const app = new cdk.App();
new MyApp(app, `test`, { env: { account: '111111111111', region: 'eu-west-1' } });
new MyApp(app, `prod`, { env: { account: '222222222222', region: 'eu-west-1' } });
我面临的问题是这会生成类似于以下内容的输出:
Successfully synthesized to [...]/my-app/cdk.out
Supply a stack id (prodpersistencestackFE36DF49, testpersistencestack6C35C777, prodapplicationstackA0A96586, testapplicationstackE19450AB) to display its template.
我希望看到的是 "nice" 堆栈名称(因为我在调用构造函数时指定了 stackName
属性):
Successfully synthesized to [...]/my-app/cdk.out
Supply a stack id (prodpersistencestack, testpersistencestack, prodapplicationstack, testapplicationstack) to display its template.
动机:我需要 "nice"(或至少是可预测的)堆栈名称来为我们的 CI/CD 管道提供下一步,以便构建服务器可以部署 CDK 应用程序。
AWS CDK 版本:1.21.1
这 AWS CDK issue 解决了这个问题。在其回复中指出,堆栈 ID 是设计使然的(因为一个人可以在多个环境中具有相同的堆栈名称)。
为了将堆栈名称用作部署参数,可以实现对 cdk.out/manifest.json
文件的反向查找,因为那里提供了堆栈 ID 和堆栈名称之间的映射信息。以下是如何使用 jq:
实现此类查找的摘录
# get stack name from somewhere, e.g. test-persistence-stack, prod-persistence-stack, test-application-stack or prod-application-stack from the question above
stackName=
# extract stack id from ./cdk.out/manifest.json
stackId=$(jq -r --arg stackName "$stackName" \
'.artifacts
| to_entries[]
| select(.value.properties.stackName == $stackName)
| .key
' \
< "./cdk.out/manifest.json" \
)
# call cdk deploy with stack id as parameter
npx cdk deploy \
--app cdk.out \
--require-approval never \
"$stackId"
在由 multiple stacks that I would like to deploy to multiple environments 组成的 AWS CDK 应用程序中执行 npx cdk synth
时如何获取 "nice" 堆栈名称?
#!/usr/bin/env node
import * as cdk from '@aws-cdk/core';
import * as s3 from '@aws-cdk/aws-s3';
import * as lambda from '@aws-cdk/aws-lambda';
class PersistenceStack extends cdk.Stack {
public readonly bucket: s3.Bucket;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
this.bucket = new s3.Bucket(this, 'bucket');
}
}
interface ApplicationStackProps extends cdk.StackProps {
bucket: s3.Bucket;
}
class ApplicationStack extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props: ApplicationStackProps) {
super(scope, id, props);
const myLambda = new lambda.Function(this, 'my-lambda', {
runtime: lambda.Runtime.NODEJS_12_X,
code: new lambda.AssetCode('my-lambda'),
handler: 'index.handler'
});
props.bucket.grantReadWrite(myLambda);
}
}
class MyApp extends cdk.Construct {
constructor(scope: cdk.Construct, id: string, props: cdk.StackProps) {
super(scope, id);
const persistenceStack = new PersistenceStack(this, 'persistence-stack', {
...props,
description: 'persistence stack',
stackName: `${id}-persistence-stack`,
});
const applicationStack = new ApplicationStack(this, 'application-stack', {
...props,
description: 'application stack',
stackName: `${id}-application-stack`,
bucket: persistenceStack.bucket,
});
applicationStack.addDependency(persistenceStack);
}
}
const app = new cdk.App();
new MyApp(app, `test`, { env: { account: '111111111111', region: 'eu-west-1' } });
new MyApp(app, `prod`, { env: { account: '222222222222', region: 'eu-west-1' } });
我面临的问题是这会生成类似于以下内容的输出:
Successfully synthesized to [...]/my-app/cdk.out
Supply a stack id (prodpersistencestackFE36DF49, testpersistencestack6C35C777, prodapplicationstackA0A96586, testapplicationstackE19450AB) to display its template.
我希望看到的是 "nice" 堆栈名称(因为我在调用构造函数时指定了 stackName
属性):
Successfully synthesized to [...]/my-app/cdk.out
Supply a stack id (prodpersistencestack, testpersistencestack, prodapplicationstack, testapplicationstack) to display its template.
动机:我需要 "nice"(或至少是可预测的)堆栈名称来为我们的 CI/CD 管道提供下一步,以便构建服务器可以部署 CDK 应用程序。
AWS CDK 版本:1.21.1
这 AWS CDK issue 解决了这个问题。在其回复中指出,堆栈 ID 是设计使然的(因为一个人可以在多个环境中具有相同的堆栈名称)。
为了将堆栈名称用作部署参数,可以实现对 cdk.out/manifest.json
文件的反向查找,因为那里提供了堆栈 ID 和堆栈名称之间的映射信息。以下是如何使用 jq:
# get stack name from somewhere, e.g. test-persistence-stack, prod-persistence-stack, test-application-stack or prod-application-stack from the question above
stackName=
# extract stack id from ./cdk.out/manifest.json
stackId=$(jq -r --arg stackName "$stackName" \
'.artifacts
| to_entries[]
| select(.value.properties.stackName == $stackName)
| .key
' \
< "./cdk.out/manifest.json" \
)
# call cdk deploy with stack id as parameter
npx cdk deploy \
--app cdk.out \
--require-approval never \
"$stackId"