[core] Removing implicit references breaks deployment
See original GitHub issueI’m using CDK Pipelines to deploy two stacks, an ApiStack
defining an AppSync API and a WebStack
defining a CloudFront distribution that makes the AppSync API available under a custom domain.
Since the WebStack
depends on the ApiStack
, CDK Pipelines updates the ApiStack
before it updates the WebStack
.
Now, I decided to remove the AppSync API from the distribution. After removing the graphQLApi
from the WebStack
, deployment fails with the CloudFormation error:
Export Staging-Api:StagingApiExportsOutputFnGetAttGraphQLApi6F81E747GraphQLUrl26BE4366 cannot be deleted as it is in use by Staging-Web
I think the error is due to the fact that CDK is more clever (or rather, has complete knowledge) compared to the CloudFormation actions.
Since the CDK knows, that ApiStack.graphQLApi
is no longer used, it removes the export from the stack. When updating the ApiStack
, however, CloudFormation is not aware that the WebStack
(which is going to be updated in the next step) no longer imports the GraphQLApi
and fails deployment.
I’m not sure how this kind of error can be fixed or prevented by the CDK …
Reproduction Steps
Before change:
const apiStack = new ApiStack(app, 'ApiStack');
new WebStack(app, 'WebStack', {
graphQLApi: apiStack.graphQLApi,
});
export class ApiStack extends cdk.Stack {
public readonly graphQLApi: appsync.GraphQLApi;
constructor(scope: cdk.Construct, id: string, props: ApiStackProps) {
super(scope, id, props);
this.graphQLApi = new appsync.GraphQLApi(this, 'GraphQLApi', {
name: `GraphQLApi`,
// ...
});
// ...
}
}
interface WebStackProps extends cdk.StackProps {
graphQLApi: appsync.GraphQLApi;
}
export class WebStack extends cdk.Stack {
// ...
constructor(scope: cdk.Construct, id: string, props: WebStackProps) {
super(scope, id, props);
const noHttps = cdk.Fn.select(1, cdk.Fn.split('//', graphQLApi.graphQlUrl));
const graphQLApiDomain = cdk.Fn.select(0, cdk.Fn.split('/', noHttps));
new cloudfront.CloudFrontWebDistribution(this, 'Distribution', {
originConfigs: [
{
customOriginSource: {
domainName: graphQLApiDomain,
},
behaviors: [
{
pathPattern: '/graphql',
// ...
}
]
},
// ...
],
// ...
});
}
}
After change:
new ApiStack(app, 'ApiStack');
new WebStack(app, 'WebStack');
export class WebStack extends cdk.Stack {
// ...
constructor(scope: cdk.Construct, id: string, props: WebStackProps) {
super(scope, id, props);
new cloudfront.CloudFrontWebDistribution(this, 'Distribution', {
originConfigs: [
// CUSTOM ORIGIN FOR GRAPHQL API REMOVED
// ...
],
// ...
});
}
}
What did you expect to happen?
No error. The CodePipeline created by CDK Pipelines is able to deploy both stacks without error.
What actually happened?
Environment
- CLI Version : 1.58.0
- Framework Version: 1.58.0
- Node.js Version: v12.16.1
- OS : macOS
- Language (Version): TypeScript (3.9.7)
This is 🐛 Bug Report
Issue Analytics
- State:
- Created 3 years ago
- Reactions:8
- Comments:7 (3 by maintainers)
Top GitHub Comments
I think this problem has been raised before. As explained in the blog article you linked it can be handled with CfnOutputs.
But for us it is a real show stopper. It is tedious and error prone. The problem is even worse when cdk must replace a dependency. You often end up with changing IDs because the old and new resources must exists at the same time.
Even worse when you have a chain of dependencies like stack A depends on stack B which depends on stack C. Replacing a resource in C could break an output across the whole chain and you have to do the CfnOutput trick multiple times. I did, it’s hard and time consuming.
I think cdk should be able to sequence partial updates that would lead to the final desired state without errors. Now I understand that this could lead to partial state not consistent with the definition due to rollbacks not being possible. But I would be glad to have it has an option.
At the very least some simple way of handling the CfnOutput trick could be a solution.
This is really hard to drop cdk because of this problem. Apart from that it is really a great tool which could help us a lot.
I believe you should be able to use
stack.exportValue()
. See https://github.com/aws/aws-cdk/pull/12778@rix0rrr can this be closed?