(CDK): Export changes prevent stack updates
See original GitHub issueWhat is the problem?
While creating a multi-stack app I am referring to resources between stacks. The CDK does a great job understanding those relationship automatically and creating an export for me.
However when a change is made in a stack that consumes resources where those resources are no longer used (in my case setting/updating Transit Gateway Routes) which have a level of dynamism based on routing traffic for inspection etc the CDK insists on deleting previous used (but now not) exports in the underlying stack.
This is blocked by CloudFormation which prevents the deletion of the stack. The ‘stack above’ cannot be updated because the ‘stack below’ doesn’t export the resources it needs for the update. Both stacks are effectively ‘locked’ from updates.
Reproduction Steps
Deploy the following with a cdk deploy --all
:
#!/usr/bin/env node
import 'source-map-support/register';
import * as cdk from '@aws-cdk/core';
import * as ec2 from '@aws-cdk/aws-ec2'
const app = new cdk.App();
// Transit Gateway Stack
class TransitGateway extends cdk.Stack {
transitGateway: ec2.CfnTransitGateway
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
this.transitGateway = new ec2.CfnTransitGateway(this, "TransitGateway", {})
}
}
const transitGatewayStack = new TransitGateway(app, 'TransitGateway', {});
// 'n' number of VPCs That will eventually use the TGW
class Vpc extends cdk.Stack {
vpc: ec2.Vpc
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
this.vpc = new ec2.Vpc(this, "Vpc", {
cidr: "10.1.0.0/16",
subnetConfiguration: [
{
name: "Public",
cidrMask: 24,
subnetType: ec2.SubnetType.PUBLIC
},
{
name: "Private",
cidrMask: 24,
subnetType: ec2.SubnetType.PRIVATE_WITH_NAT
},
{
name: "TransitGateway",
cidrMask: 28,
subnetType: ec2.SubnetType.PRIVATE_ISOLATED
}
]
})
}
}
const vpcStack = new Vpc(app, "Vpc", {})
// I'm deploying many more VPCs in this stage, along with firewalls, gateway load balancers etc
// Finally have a stack that wires them all together via the TGW
class TransitRoutes extends cdk.Stack {
constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
const association = new ec2.CfnTransitGatewayVpcAttachment(this, "VpcAttach", {
transitGatewayId: transitGatewayStack.transitGateway.attrId,
subnetIds: vpcStack.vpc.selectSubnets({subnetGroupName: "TransitGateway"}).subnetIds,
vpcId: vpcStack.vpc.vpcId
})
vpcStack.vpc.selectSubnets({subnetGroupName: "Public"}).subnets.forEach((subnet, index) => {
const route = new ec2.CfnRoute(this, `RouteToTGW${index}`, {
routeTableId: (subnet as ec2.Subnet).routeTable.routeTableId,
destinationCidrBlock: "10.100.2.0/24",
transitGatewayId: transitGatewayStack.transitGateway.attrId
})
route.node.addDependency(association)
})
}
}
const transitRoutesStack = new TransitRoutes(app, "TransitRoutes", {})
After it has deployed successfully. Change line 59 to be Private
instead of Public
. ie:
vpcStack.vpc.selectSubnets({subnetGroupName: "Private"}).subnets.forEach((subnet, index) => {
Attempt to deploy changes. CDK will attempt to delete the RouteTableID exports for the public subnets in the Vpc Stack. This will be prevented because the TransitGateway Stack depends on them. Neither stack can be updated at this point.
What did you expect to happen?
The CDK would understand a previously used export was possibly / probably still in use and preserve it. I don’t see a lot of value in deleting an existing export? Where an export has been created, I’d expect it to exist for the life-cycle of the stack.
Where that’s not possible some kind of ‘exportAll()’ method on a construct would come in handy!
What actually happened?
CDK insists on deleting the now unused export which locks both stacks up preventing either from being updated.
CDK CLI Version
1.134.0 (build dd5e12d)
Framework Version
No response
Node.js Version
v14.18.1
OS
OSX 11.6.1
Language
Typescript
Language Version
3.9.10
Other information
No response
Issue Analytics
- State:
- Created 2 years ago
- Comments:5 (2 by maintainers)
Top GitHub Comments
Alright, I think if I’m going to put the effort into naming exports and managing all that between stacks, I’ll just switch to using SSM parameters. Looser coupling. Thanks!
⚠️COMMENT VISIBILITY WARNING⚠️
Comments on closed issues are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.