简体   繁体   中英

Create predicatable stack names for multiple stacks in AWS CDK

How can I get "nice" stack names when executing npx cdk synth in an AWS CDK application that is made up of multiple stacks that I would like to deploy to multiple environments ?

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

The problem that I am facing is that this generates outputs similar to:

Successfully synthesized to [...]/my-app/cdk.out
Supply a stack id (prodpersistencestackFE36DF49, testpersistencestack6C35C777, prodapplicationstackA0A96586, testapplicationstackE19450AB) to display its template.

What I expected to see is "nice" stack names (since I have specified the stackName properties when calling the constructors):

Successfully synthesized to [...]/my-app/cdk.out
Supply a stack id (prodpersistencestack, testpersistencestack, prodapplicationstack, testapplicationstack) to display its template.

Motivation: I need "nice" (or at least predictable) stack names to feed into the next step our CI/CD pipeline so that the build server can deploy the CDK app.

AWS CDK version: 1.21.1

This AWS CDK issue addresses this concern. In its response it is stated that the stack ids are like this by design (since one can have the same stack name in multiple environments).

In order to use the stack name as a deployment parameter, one can implement a reverse lookup of the cdk.out/manifest.json file because the mapping information between stack ids and stack names is available there. Below is an excerpt of how such a lookup can be implemented using 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"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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