From 1fae95158d7631dc2f7457a64aac9faeaa8f1920 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=F0=9F=A7=91=F0=9F=8F=BB=E2=80=8D=F0=9F=92=BB=20Romain=20M?= =?UTF-8?q?arcadier?= Date: Mon, 5 Dec 2022 12:34:42 +0100 Subject: [PATCH 1/2] fix(toolkit): endless wait if CDKToolkit stack is `REVIEW_IN_PROGRESS` If a `cdk bootstrap` operation is interrupted after the ChangeSet has been created, but before it is executed, the CDKToolkit stack will be left in the `REVIEW_IN_PROGRESS` state, which is a stable state until something or someone either executes or deletes the pending ChangeSet. This resulted in an endless (and silent, unless `cdk bootstrap` is executed in verbose mode) wait, as this was considered an "in progress" (aka unstable) state. This changes `REVIEW_IN_PROGRESS` to be treated as stable, while still debug-logging an indication that we are "ignoring" the existing ChangeSet. --- packages/aws-cdk/lib/api/util/cloudformation.ts | 8 ++++++++ .../aws-cdk/lib/api/util/cloudformation/stack-status.ts | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/aws-cdk/lib/api/util/cloudformation.ts b/packages/aws-cdk/lib/api/util/cloudformation.ts index e4fa597e506b4..b458f28ddb5a2 100644 --- a/packages/aws-cdk/lib/api/util/cloudformation.ts +++ b/packages/aws-cdk/lib/api/util/cloudformation.ts @@ -371,6 +371,14 @@ export async function stabilizeStack(cfn: CloudFormation, stackName: string) { if (status.isInProgress) { debug('Stack %s has an ongoing operation in progress and is not stable (%s)', stackName, status); return undefined; + } else if (status.isReviewInProgress) { + // This may happen if a stack creation operation is interrupted before the ChangeSet execution starts. Recovering + // from this would requiring manual intervention (deleting or executing the pending ChangeSet), abd failing to do + // so will result in an endless wait here (the ChangeSet wont delete or execute itself). Instead of blocking + // "forever" we proceed as if the stack was existing and stable. If there is a concurrent operation that just + // hasn't finished proceeding just yet, either this operation or the concurrent one may fail due to the other one + // having made progress. Which is file. I guess. + debug('Stack %s is in REVIEW_IN_PROGRESS state. Considering this is a stable status (%s)', stackName, status); } return stack; diff --git a/packages/aws-cdk/lib/api/util/cloudformation/stack-status.ts b/packages/aws-cdk/lib/api/util/cloudformation/stack-status.ts index 76069868cf99b..8e2ae674a9074 100644 --- a/packages/aws-cdk/lib/api/util/cloudformation/stack-status.ts +++ b/packages/aws-cdk/lib/api/util/cloudformation/stack-status.ts @@ -26,7 +26,11 @@ export class StackStatus { } get isInProgress(): boolean { - return this.name.endsWith('_IN_PROGRESS'); + return this.name.endsWith('_IN_PROGRESS') && !this.isReviewInProgress; + } + + get isReviewInProgress(): boolean { + return this.name === 'REVIEW_IN_PROGRESS'; } get isNotFound(): boolean { From 33eb4c91add0d47d0d67e4b4e4d5e27a3d96cd04 Mon Sep 17 00:00:00 2001 From: Romain Marcadier Date: Wed, 7 Dec 2022 14:46:44 +0100 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Ryan Parker --- packages/aws-cdk/lib/api/util/cloudformation.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/aws-cdk/lib/api/util/cloudformation.ts b/packages/aws-cdk/lib/api/util/cloudformation.ts index b458f28ddb5a2..66f7752371f7c 100644 --- a/packages/aws-cdk/lib/api/util/cloudformation.ts +++ b/packages/aws-cdk/lib/api/util/cloudformation.ts @@ -373,11 +373,11 @@ export async function stabilizeStack(cfn: CloudFormation, stackName: string) { return undefined; } else if (status.isReviewInProgress) { // This may happen if a stack creation operation is interrupted before the ChangeSet execution starts. Recovering - // from this would requiring manual intervention (deleting or executing the pending ChangeSet), abd failing to do + // from this would requiring manual intervention (deleting or executing the pending ChangeSet), and failing to do // so will result in an endless wait here (the ChangeSet wont delete or execute itself). Instead of blocking // "forever" we proceed as if the stack was existing and stable. If there is a concurrent operation that just // hasn't finished proceeding just yet, either this operation or the concurrent one may fail due to the other one - // having made progress. Which is file. I guess. + // having made progress. Which is fine. I guess. debug('Stack %s is in REVIEW_IN_PROGRESS state. Considering this is a stable status (%s)', stackName, status); }