aws-cdk remove resource from stack that used in another stack

Viewed 1831

Try to understand a strange behavior of CDK:

I have 2 stacks

StackA -> define resource outA

StackB -> define resource outB - its depend on resource outA

the first 'CDK deploy' is run without any problem.

Now I change StackA by deleting 'outA' resource and create a new resource call 'outAnew' and update StackB to use this new value

at this time I can't deploy any Stack! if I try to deploy StackA got error:

Export outA cannot be deleted as it is in use by StackB and StackC

and if try to deploy StackB it first tries to deploy StackA because of the dependency.

any Idea?

Example code:

StackA:

export class CdkDependenciesStackA extends cdk.Stack {
// public out_a: cdk.CfnOutput;
public out_a_new: cdk.CfnOutput;
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// this.out_a = new cdk.CfnOutput(this, "out_a", {
//   value: "outA",
//   exportName: "outA",
// });
this.out_a_new = new cdk.CfnOutput(this, "out_a_new", {
  value: "outAnew",
  exportName: "outAnew",
});

} 
}

StackB:

export class CdkDependenciesStackB extends cdk.Stack {
    public out_b: cdk.CfnOutput;
    constructor(
      scope: cdk.Construct,
      id: string,
      outputValue: cdk.CfnOutput,
      props?: cdk.StackProps
    ) {
      super(scope, id, props);
      this.out_b = new cdk.CfnOutput(this, "out_b", {
        value: `outB_${outputValue.importValue}`,
        exportName: "outB",
       });
    }
  }

App:

const app = new cdk.App();
const stack_a = new stacks.CdkDependenciesStackA(
  app,
  "CdkDependenciesStack",
  {}
   );

 const stack_b =new stacks.CdkDependenciesStackB(
   app,
   "CdkDependenciesStackB",
   stack_a.out_a_new,
   {}
  );
 stack_b.addDependency(stack_a)
2 Answers

This seems to be common problem across CDK userbase. The solution that helped me is described at https://aws-blog.de/2020/09/deployment-issues-with-cross-stack-dependencies-and-the-cdk.html

Since the stack that is exporting values is deployed first, you still need to keep that original export so that

  • Exporting stack can be deployed to export new value
  • Importing stack can be deployed to import new value and stop importing old value

After that you can stop exporting the old value.

This is Stack Dependency and it can be a real big bear to deal with. You have to put your stacks back to the original value. Then add a dummy value in the second stack (that depends on the original resource) and push it. Then remove it from the original stack and replace it, then replace it in the second stack.

Better however, if these two stacks always will depend on each other, make them both NestedStacks and put them together in the same common stack to deploy all at once. Still keep your separation in code, but everything deploys all together.

If that is a problem (deploying all together) you can hack your way through it by using the various methods that start with from to import a resource from another stack rather than depending on it as a passed parameter. This is prone to a lot of other issues (as hacks usually are) as many of the from methods are not capable of getting all the information, plus unless you set up some kind of automatic naming scheme yourself, it becomes difficult to deploy multiple environments. (a key bonus of CDK)

Related