Skip to content

Comments

feat(gen2-migration): implement holding stack for Gen2 resource retention during refactor#14604

Open
9pace wants to merge 12 commits intogen2-migrationfrom
rollback/retain-temporary-resources
Open

feat(gen2-migration): implement holding stack for Gen2 resource retention during refactor#14604
9pace wants to merge 12 commits intogen2-migrationfrom
rollback/retain-temporary-resources

Conversation

@9pace
Copy link

@9pace 9pace commented Feb 19, 2026

Description of changes

During forward migration, Gen2 stateful resources are now moved to a temporary holding stack instead of being deleted. This preserves test data that customers may have created while testing the Gen2 deployment.

Issue #, if available

#14531

Description of how you validated changes

Ran manual flow of forward refactor and rollback on discussions app.

Checklist

  • PR description included
  • yarn test passes
  • Tests are changed or added
  • Relevant documentation is changed or added (and PR referenced)
  • New AWS SDK calls or CloudFormation actions have been added to relevant test and service IAM policies
  • Pull request labels are added

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

9pace added 10 commits February 6, 2026 14:41
Changes:
- Implement rollback() to call executeRollback() via the operation
  pattern
- Remove unused isRollback instance variable (dispatcher handles
  routing)
- Skip rollbackValidate() for now (tracked in #14579)

The original commit 5f74c2e was written against an older step
interface. After the merge from gen2-migration branch, the interface
changed to use separate execute/rollback methods with the operation
pattern. This commit adapts the rollback implementation to the new
interface.
…ctor module

Standardize naming conventions in the refactor module by replacing all
"revert" terminology with "rollback" for consistency. This change
affects the public API, internal methods, constants, tests, and
documentation.

Changes:
- Rename public revert() method to rollback() in TemplateGenerator
- Rename LOGICAL_IDS_TO_REMOVE_FOR_REVERT_MAP constant to
  LOGICAL_IDS_TO_REMOVE_FOR_ROLLBACK_MAP
- Rename private methods: generateRefactorTemplatesForRevert to
  generateRefactorTemplatesForRollback, buildSourceToDestinationMapForRevert
  to buildSourceToDestinationMapForRollback
- Rename parameters: isRevert to isRollback throughout the codebase
- Update test descriptions and assertion function names
- Update refactor.md documentation
---
Prompt: Currently there are two naming conventions for rollback in
refactor. There is both revert and rollback. I would like to unify the
naming such that we only use the rollback terminology.
…ctor

During forward migration, Gen2 stateful resources are now moved to a
temporary holding stack instead of being deleted. This preserves test
data that customers may have created while testing the Gen2 deployment.

Changes:
- Add holding-stack.ts with utilities for creating, finding, and
  deleting holding stacks
- Add initializeGen2State() to set up Gen2 state before holding stack
  move
- Add moveGen2ResourcesToHoldingStack() to move Gen2 resources via
  StackRefactor
- Add restoreGen2ResourcesFromHoldingStack() for rollback
- Implement cleanup command to delete remaining holding stacks
- Fix pre-existing bug: pass implementation instead of step config to
  CachedAmplifyMigrationStep
- Export HOLDING_STACK_SUFFIX from holding-stack.ts to avoid
  duplication

Forward flow: Gen2 resources -> Holding stack, then Gen1 -> Gen2
Rollback flow: Gen2 -> Gen1, then Holding stack -> Gen2
---
Prompt: Implement holding stack functionality such that on refactor,
gen2-resources are retained rather than deleted. The holding stack
operation should be similar to the deletion operation: resolve gen2
template, then StackRefactor from gen2 stack to holding stack per
category.
… display bugs

After a successful Gen2-to-holding-stack StackRefactor, if the
subsequent Gen1-to-Gen2 refactor crashed (or was interrupted),
retries would fail with an assertion error in
addGen1ResourcesToGen2Stack. The root cause was that
processGen2Stack re-read the Gen2 template (now missing its
stateful resources), found zero resources, fell through to
generateGen2ResourceRemovalTemplate which overwrote
gen2ResourcesToRemove to empty, producing an empty logical ID
mapping. The assert(gen2ResourceLogicalId) then fired on every
Gen1 resource.

Fix: Add recoverFromHoldingStack() to CategoryTemplateGenerator.
On entry, processGen2Stack now checks for an existing holding
stack. If one is found with stateful resources, it populates
gen2ResourcesToRemove from the holding stack contents and returns
the current Gen2 template, skipping the already-completed move.
The redundant generateGen2ResourceRemovalTemplate fallback path
is removed entirely.

Additional fixes in this commit:

- Extract filterStatefulResources() helper to eliminate four
  copies of the same resource-type filtering logic across
  initializeGen2State, generateGen1PreProcessTemplate,
  generateGen2ResourceRemovalTemplate, and the new recovery
  method.

- Fix implications display in gen2-migration.ts. The code was
  iterating over AmplifyMigrationOperation[] objects (from
  cachedStep.execute()) and printing them as strings, producing
  '• [object Object]'. Changed to call executeImplications() /
  rollbackImplications() which return string[].

- Fix deleteHoldingStack crash when the stack is already gone.
  The function called DeleteStack then pollStackForCompletionState
  which threw 'does not exist' from DescribeStacks. Now guards
  with findHoldingStack before attempting deletion.

- Update refactor.md with known issues and fix status for the
  holding stack implementation.
---
Prompt: Review the code I added to make a holding stack instead
of deleting the resources in gen 1 -> gen2 migration. The
original code had generateGen2ResourceRemovalTemplate, which
would remove resources from gen2, making space for the refactor
in gen 1, what i have added is that prior to this removal
template, all gen 2 stateful resources are refactored to
temporary "holding stacks" which will make it such that they
are not deleted. The implementation is likely a little buggy and
not 100% correct. I have run it once in failure.
@9pace 9pace requested a review from a team as a code owner February 19, 2026 22:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant