If a stack is in UPDATE_FAILED and its deployed template already matches the one being deployed, the change set comes back empty and cdk deploy reports success and exits 0 while the stack is still failed. With --force it additionally asserts "According to CloudFormation, all resources are already up-to-date with the state in your CDK app."
This is not Express Mode specific: it needs only a failed-but-updatable stack and a matching template. A failed express deployment reaches it easily, because rollback is disabled server-side so the stack stays in UPDATE_FAILED rather than rolling back.
changeSetDeployment() returns early on changeSetHasNoChanges() (deploy-stack.ts ~:474), before checkAndExecuteChangeSet(), and never consults this.cloudFormationStack.stackStatus — which is already loaded and already knows the stack is failed. waitForStackDeploy sets the precedent for the other direction, throwing DeploymentError on !status.isDeploySuccess (cfn-api.ts:421-423).
Changing the exit code is a cx-facing contract change: it will turn currently-green pipelines red, including ones that are green only because they repeatedly no-op deploy a long-failed stack. A lower-risk first step is to keep exit 0, warn with the stack status, and suppress the "already up-to-date" claim when the stack is not in a successful state.
Repro: strand a stack (see #1931), revert the source to match it, then cdk deploy. Out of scope for #1969, which neither fixes nor depends on this; note the unwedge documented in #1970 works around it using --method=direct.
#NNNN here means aws/aws-cdk-cli; note aws/aws-cdk#1931 is an unrelated closed issue.
If a stack is in UPDATE_FAILED and its deployed template already matches the one being deployed, the change set comes back empty and
cdk deployreports success and exits 0 while the stack is still failed. With--forceit additionally asserts "According to CloudFormation, all resources are already up-to-date with the state in your CDK app."This is not Express Mode specific: it needs only a failed-but-updatable stack and a matching template. A failed express deployment reaches it easily, because rollback is disabled server-side so the stack stays in UPDATE_FAILED rather than rolling back.
changeSetDeployment()returns early onchangeSetHasNoChanges()(deploy-stack.ts~:474), beforecheckAndExecuteChangeSet(), and never consultsthis.cloudFormationStack.stackStatus— which is already loaded and already knows the stack is failed.waitForStackDeploysets the precedent for the other direction, throwingDeploymentErroron!status.isDeploySuccess(cfn-api.ts:421-423).Changing the exit code is a cx-facing contract change: it will turn currently-green pipelines red, including ones that are green only because they repeatedly no-op deploy a long-failed stack. A lower-risk first step is to keep exit 0, warn with the stack status, and suppress the "already up-to-date" claim when the stack is not in a successful state.
Repro: strand a stack (see #1931), revert the source to match it, then
cdk deploy. Out of scope for #1969, which neither fixes nor depends on this; note the unwedge documented in #1970 works around it using--method=direct.#NNNNhere meansaws/aws-cdk-cli; noteaws/aws-cdk#1931is an unrelated closed issue.