Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting stackName of Stack inside the Stack #7784

Closed
MitchellJeppson opened this issue May 4, 2020 · 14 comments
Closed

Allow setting stackName of Stack inside the Stack #7784

MitchellJeppson opened this issue May 4, 2020 · 14 comments
Assignees
Labels
@aws-cdk/core Related to core CDK functionality feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged.

Comments

@MitchellJeppson
Copy link

Currently you can explicitly set the stack name by passing in the stackName prop to a Stack. It would be nice to be able to dynamically set the stack name within the Stack implementation.

Use Case

I would like to be able to use a stack parameter in the stack name. For example I have parameters cluster=BigCluster and JobNumber=123. I would like the name of my stack to be MyStack-BigCluster-123

Proposed Solution

a setStackName(String) method in Stack would be ideal.

This is a 🚀 Feature Request

@MitchellJeppson MitchellJeppson added feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged. labels May 4, 2020
@SomayaB SomayaB added the @aws-cdk/core Related to core CDK functionality label May 6, 2020
@eladb
Copy link
Contributor

eladb commented May 6, 2020

You can achieve this by simply passing in the stack name to the super call like this:

interface MyStackProps extends StackProps {
  cluster: string;
  jobNumber: number;
}

class MyStack extends Stack {
  constructor(scope: Construct, id: string, props: MyStackProps) {
    super(scope, id, {
      stackName: `MyStack-${props.jobNumber}-${props.cluster}`,
      ...props // before/after will impact if consumers can specify a custom `stackName`
    });
}

Closing for now. Let me know if this is what you are after.

@eladb eladb closed this as completed May 6, 2020
@MitchellJeppson
Copy link
Author

Hey Elad, thanks for the quick reply. Unfortunately this is still not quite what I am looking for. My stack takes in a few CfnParameters and I would like to use those in my stack name. So in that case I cannot pass them into the props of the stack as they will not be initialized by then. For a simple example:

class MyStack extends Stack {
  constructor(scope: Construct, id: string, props: StackProps) {
    super(scope, id, props);

    const clusterParam = new CfnParameter(this, "ClusterId", {
      type: "String",
      description: "My Cluster"
    });

    //This is what I would like to be able to do
    this.setStackName("MyStack-" + clusterParam.valueAsString);
  }
}

@eladb
Copy link
Contributor

eladb commented May 6, 2020

@MitchellJeppson this is not really something we can support. Parameters are resolved only during deployment, and we need to know stack names during synthesis...

@mohdarshad
Copy link

How to achieve this in Java?

@seriouscoderone
Copy link

I ran into this problem while trying to solve environment deployment concerns. I want an "Environment" CloudFormation parameter.

I am not a fan of synthesizing per environment. I much prefer a "Build once, deploy many" approach to deploying to environments. One CloudFormation and artifacts that will be deployed to any environment.

I realized that I can "default" the CfnParameter and hard code the build-time stackName to the initial environment. The stack name can then be set on subsequent deployments.

Problem solved.

@weickmanna
Copy link

@seriouscoderone want to do the same thing. how exactly do you set the stack name on the subsequent deployments?

@weickmanna
Copy link

@seriouscoderone found this helpful article that explains how mult-env deployments are conceptualized in CDK:
https://taimos.de/blog/deploying-your-cdk-app-to-different-stages-and-environments

Does not exactly solve the problem described here, as it is not "build once, deploy many". But this gave us a solid understanding of how these deployments are meant to work in CDK and that happened to be fine for us.

@krnbr
Copy link

krnbr commented Jun 24, 2021

@seriouscoderone do you mind sharing more details?

@krnbr
Copy link

krnbr commented Jun 24, 2021

@eladb how can we pass these values? using command line or env?

env is a possibility - straight forward enough.

what about as arguments to the cdk deploy command? how to do that?

Is there any in built support? or one will have to write custom stuff?

interface MyStackProps extends StackProps {
  cluster: string;
  jobNumber: number;
}

@lyonzy
Copy link

lyonzy commented Aug 31, 2021

@eladb I was wondering if I could request that this be reopened/revisited. My team is rebuilding our application on CDK and we have a lot of shared AWS accounts, meaning we need some way to distinguish resources and stacks across environments. Resources are fine (we can do those with CFn parameters) but there doesn't seem to be a way to change or parameterise the name of the stack itself at deploy time.

For the same reasons Michael specified above and others mentioned in #2636, we'd really like to "build once deploy repeatedly" because we don't necessarily have (or want) access to Java/Maven/our code asset repo at deploy time. Ruling out synth-time modification rules out anything in Java (e.g. arguments/env vars as was posted above).

So firstly is there anything I'm missing? It seems stackName is validated to a regex that's "numbers/letters/dashes" and blocks ${} references - unless I'm missing some substitution somewhere. I overrode the getStackName() method (in Java) and this created a manifest.json with ${} references in stackNames - but then cdk deploy tried to deploy it with that exact name which then failed in CloudFormation.

If I've got all that right then can I request either:

  • ${Qualifier} gets substituted into the stack name at some point before deployment (and the regex is run on the name with that removed) - not sure whether this is the correct use for Qualifier though
  • a new param on cdk deploy that allows a prefix to be set on the stack name(s)

Anything that means we can run a cdk deploy --app ./cdk.out --[something]="DEV" and have stacks created with a name of DEV-Resource-Stack would be ideal. As a workaround I'm considering substituting fields in manifest.json manually before deployment, which gets us what we need but it's a bit of a hack.

@rlpowell
Copy link

rlpowell commented Sep 6, 2021

FYI #9261 shows a way to handle some of this that worked for me.

@lyonzy
Copy link

lyonzy commented Sep 7, 2021

Thanks, that's an answer for the synth phase but I was really hoping to do a "synth once deploy many" approach which would mean it would need to synthesise with a placeholder value of some kind that deploy understands.

@adrian-baker
Copy link

adrian-baker commented Sep 9, 2021

This was a surprise to me as well, but it seems quite a deliberate design decision:

All your target deployment environments are fully configured in your source code, rather than parameterizing a deployment artifact to be configured later.

So practically it can be done by defining multiple copies of your stack (https://docs.aws.amazon.com/cdk/latest/guide/stack_how_to_create_multiple_stacks.html), then specifying which one from that menu at deploy time. So it's still synth once deploy many, it's just that the deploy must stick within the set of stack names defined in synth. After build, if you want to deploy my-stack-experiment-copy without code changes, well, you can't.

Not really ideal if you are already defining a separate set of deployments/stacknames in pipeline deploy code elsewhere that your stack might have previously remained happily unaware of (eg you might just have nothing more than a "small"/"large" parameter in a stack but leave all the naming of actual stacks to pipeline deploy code: thats not possible in cdk, your set of stack names must be now defined twice, in two places).

It also makes me uncomfortable that under the hood a separate template json is generated for each separate copy of the stack. Which feels like anti-pattern given that the idea is to absolutely minimise differences between environments, which previously would be encouraged by deploying the same actual template file multiple times.

At first I though the environment concept might help model this, but it's not a very good concept of "environment", because it assumes each stack only exists once in an account (it should just be named "Account").

Possibly you could only use cdk synth then standard cli to deploy with --stack-name (but it has zero progress logging or error reporting), or sam deploy (but who wants to mix multiple cloudformation tools each with different conceptual models and cli quirks).

@lyonzy
Copy link

lyonzy commented Sep 9, 2021

Yeah I agree with all your points. Our topology is application code in one area, and a separate set of configs for each environment. We're developing for a fairly large organisation and they often tell us to set up a new environment for a specific program of work, and we don't really want to be re-releasing a new version of our codebase to accommodate that. I guess if you were strictly "multi account" (we are for production and a few others, just not dev/test) then you could work with fixed stack names.

Good idea with the sam deploy but I was really hoping to take advantage of assets (we have a lot of Lambdas and have a bit of an asset management strategy that we could offload almost fully to the CDK) - and if we were going to try and deploy with CloudFormation we'd need to bake that custom asset management back in (as well as learn how to parse the cdk.out files).

TBH I think for now we'll just do something like envsubst < manifest.json (based on this) before deploying, until there's a better answer supported in the CDK.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/core Related to core CDK functionality feature-request A feature should be added or improved. needs-triage This issue or PR still needs to be triaged.
Projects
None yet
Development

No branches or pull requests

10 participants