Skip to content

Commit c86f4e5

Browse files
sai-rayiliapoloSai Ray
authored
feat(gen2-migration): geo category for gen2-migration. (#14712)
* feat(cli-internal): add assess, refactor, and generate-new commands Squash of all work on the migration-plan branch since diverging from gen2-migration. Includes the assess subcommand for migration readiness, the refactor command rebuild with category-specific forward/rollback refactorers, the generate-new infrastructure with Generator+Renderer pattern, unified validation model, SpinningLogger UX, and comprehensive unit tests. --- Prompt: squash all commits after the merge base with gen2-migration into one and commit * chore: fix test * test(cli-internal): replace null-as-any logger with noOpLogger helper Add a noOpLogger() test helper that creates a real SpinningLogger in debug mode, then replace all `null as any` logger arguments across 8 refactor test files with it. This improves type safety without changing test behavior since the logger methods are never exercised in these tests. All 30 tests pass. --- Prompt: In the refactor test directory there are lot of null as any being used to pass a spinning logger instance - change it to actually create a proper logger instance. * feat(cli-internal): print validation report on failure Plan.validate() now captures the report field from ValidationResult and renders a "Failed Validations Report" section before the summary table. Each failed validation shows its description in red followed by the report text. Also trims the drift report in _validations.ts. --- Prompt: The report property in ValidationResult is currently not used at all. We should use to print the validation report in case the validation failed. * refactor(cli-internal): classify auth stacks by resource type Replace description-JSON-based auth stack classification with resource-type detection. The new approach checks for the presence of an AWS::Cognito::UserPool resource instead of parsing the stack Description field, which is more reliable. Also rename fetchStackDescription to fetchStack and descriptionCache to stackCache for accuracy since the method returns the full Stack object. --- Prompt: commit what I did * refactor(cli-internal): split auth refactorers and improve resource mapping Split monolithic auth-forward/rollback/utils into separate files for Cognito and UserPoolGroups, enabling independent forward and rollback refactoring per auth sub-resource. Replace gen1LogicalIds map with abstract targetLogicalId() method on RollbackCategoryRefactorer, giving each subclass explicit control over logical ID resolution. Extract match() hook on ForwardCategoryRefactorer for type-matching customization. Thread DiscoveredResource through CategoryRefactorer base class so refactorers can use resource metadata (e.g. resourceName) for stack discovery instead of relying on shared utility functions. Minor fixes to migration app docs and sanitize script (trailing newline normalization). --- Prompt: commit what I have * revert(cli-internal): remove trailing-newline normalization from sanitize --- Prompt: I reset the changes. just commit. * chore: remove merge markers * chore: cleanup * feat(cli-internal): group plan operations by resource Thread DiscoveredResource through all resource-backed planners so each operation carries the resource it belongs to. Plan.describe() now groups operations under resource headers using the format "<resourceName> (<category>/<service>)", matching the assessment display style. Ungrouped operations (scaffolding, validations) render as a flat list. Changes: - Add optional `resource` field to AmplifyMigrationOperation - Update Plan.describe() to group by resource label - Thread DiscoveredResource into all generate-side planners (Auth, ReferenceAuth, Data, S3, DynamoDB, RestApi, Function, AnalyticsKinesis) replacing separate resourceName params - Tag refactor-side operations via CategoryRefactorer and its forward/rollback subclasses (already had this.resource) - Update all affected test files with DiscoveredResource objects --- Prompt: in the gen2-migration, i want to make the plan describe itself by listing the description of each operation per resource. * fix(cli-internal): tweak plan resource group display Change label format to "category/resourceName (service)", add cyan color to group headers, remove indentation on grouped items, and add blank lines between groups for readability. --- Prompt: i've made changes * feat(cli-internal): refine plan display and support UserPool Groups rollback Group all operations under labeled sections — resource-backed ops use "Resource: category/name (service)", ungrouped ops fall under "Project". Descriptions rendered in gray for visual hierarchy. Add auth:Cognito-UserPool-Groups support in refactor assess and rollback using AuthUserPoolGroupsRollbackRefactorer. --- Prompt: I've made more changes. commit * docs: add commit OOM prevention and scratch file cleanup Add NODE_OPTIONS="--max-old-space-size=8192" to the commit command example and instructions to delete the scratch commit message file after a successful commit. --- Prompt: add an instruction in AGENTS.md to delete the commit file after committing and always increase memory size to prevent lint failures * feat(cli-internal): add changeset preview and move table to refactor plan Enrich the refactor plan output with changeset reports and formatted move tables so operators can review exactly what each operation will change before executing. Key changes: - Auth cognito: explicit client matching (GEN1_WEB_CLIENT ↔ GEN2_WEB_CLIENT, GEN1_NATIVE_APP_CLIENT ↔ GEN2_NATIVE_APP_CLIENT) replacing negation-based logic. Exported shared constants. - Auth user pool groups: extracted RESOURCE_TYPES constant, use USER_POOL_GROUP_TYPE consistently. - category-refactorer: added changeset preview via CreateChangeSetCommand/DescribeChangeSetCommand, made updateSource/updateTarget/buildMoveOperations/beforeMovePlan async, enriched plan descriptions with changeset reports and move tables. - forward/rollback-category-refactorer: updated to async signatures, added move table formatting to descriptions. - Removed validateSingleResourcePerCategory from refactor.ts. - Plan output now uses numbered steps and bold labels. - New files: changeset-report.ts, template-diff.ts, move-table.ts (formatting utilities). - Test stubs updated for new CFN commands. --- Prompt: I've made changes - commit what i've done. dont run tests or anything, just commit. * fix(cli-internal): improve changeset report formatting Use full JSON path (Target.Path) instead of just the top-level property name so duplicate property names like RoleMappings are distinguishable. Show before/after values on separate lines for readability. Use bgGray chalk headers for operation descriptions. Minor spacing tweaks in plan output and move table. --- Prompt: I've made more changes. Commit them. not tests. * refactor(cli-internal): use cli-table3 for move table and fix changeset no-changes detection Replace hand-rolled box-drawing move table with cli-table3 (CLITable) to match existing patterns. Fix changeset no-changes detection: a CREATE_COMPLETE changeset with an empty Changes list is the actual no-changes case, not a waiter failure. formatChangeSetReport now returns undefined when there are no changes. Remove debug 'bubu' suffix from cfn-output-resolver. --- Prompt: commit * feat(cli-internal): validate stack updates via changeset during refactor plan Move changeset creation into the validation lifecycle of updateSource/updateTarget operations. formatChangeSetReport returns undefined when no changes are detected. The validation checks report === undefined (valid) and surfaces the changeset report on failure. The describe output shows the report regardless. Removed unused chalk and formatTemplateDiff imports. --- Prompt: Commit. Don't run tests yet. * test(cli-internal): fix gen2-migration refactor tests Add CreateChangeSetCommand/DescribeChangeSetCommand mocks to the CloudFormationMock framework and individual test files that call plan(). Update tests for API changes: renamed module paths (auth-forward → auth-cognito-forward), new abstract targetLogicalId method on RollbackCategoryRefactorer, async beforeMovePlan, updated error message format, and Cognito-UserPool-Groups now being supported. Remove dead auth-utils.test.ts for deleted module. All 376 gen2-migr * refactor(cli-internal): improve refactor workflow resilience Improve category refactorer resilience for partial failure recovery and multi-stack auth scenarios: - Handle empty change-sets gracefully when source/target templates match deployed state (partial failure recovery) - Support reusing existing holding stacks in forward path for auth's two-gen1-stack-to-one-gen2-stack mapping - Consolidate rollback restore-from-holding into a single operation instead of three separate ops - Add logging before stack update/move/refactor operations - Improve plan step formatting (remove extra blank lines, add trailing newline to move table) - Use clearer descriptions for empty change-set validation --- Prompt: commit my changes * refactor(cli-internal): add physicalResourceId to MoveMapping Move physicalResourceId onto MoveMapping so it is populated once during buildResourceMappings and carried through the entire refactor pipeline. This eliminates redundant fetchStackResources calls in buildMoveOperations and the separate physicalIds/types maps that were threaded to formatMoveTable. - buildResourceMappings is now async; forward fetches from gen1Env, rollback from gen2Branch. - buildBlueprint is now async to await buildResourceMappings. - Deleted move-table.ts; renderMappingTable is now a protected method on CategoryRefactorer accepting MoveMapping[]. --- Prompt: in category-refactorer - I want to add the physical resource id to MoveMapping. Also make formatMoveTable accept MoveMapping[] and remove the unnecessary maps being passed to it. Remove move-table.ts and put formatMoveTable into a protected method inside CategoryRefactorer. Rename formatMoveTable to renderMappingTable. * refactor(cli-internal): hoist computation out of callbacks and simplify error handling Move all non-mutating work out of execute/describe/validate callbacks so errors surface during planning before any mutations run. tryRefactorStack and tryUpdateStack now throw on failure instead of returning result objects, eliminating boilerplate checks at every call site. createChangeSetReport now cleans up its changeset via try/finally. Deleted unused legacy-custom-resource.ts and template-diff.ts. --- Prompt: hoist computation out of execute callbacks, make tryRefactorStack and tryUpdateStack throw on failure, createChangeSetReport should delete its changeset, remove legacy-custom-resource.ts and template-diff.ts. * refactor(cli-internal): consolidate CFN operations into Cfn class Introduce a Cfn class that centralizes all CloudFormation operations (update, refactor, createChangeSet, findStack, deleteStack, renderChangeSet) behind a single client instance. Replace custom polling with SDK waiters (waitUntilStackUpdateComplete, waitUntilStackRefactorCreate/ ExecuteComplete, waitUntilStackDeleteComplete). Delete refactorer.ts (re-export of Planner), holding-stack.ts, cfn-stack-updater.ts, cfn-stack-refactor-updater.ts, changeset-report.ts, and snap.ts. Move getHoldingStackName and HOLDING_STACK_SUFFIX into CategoryRefactorer. Inline snapshot writing into cfn.ts. --- Prompt: consolidate 3 CFN operations into a Cfn class, replace custom polling with SDK waiters, remove refactorer.ts, holding-stack.ts, snap.ts, changeset-report.ts, inline snap into cfn.ts, remove resolveStackName, move ensureOutputDirectory to constructor. * refactor(cli-internal): add SpinningLogger to Cfn class Cfn now accepts a SpinningLogger and logs info messages before every wait operation (stack update, refactor create/execute, source/destination verification, stack deletion). --- Prompt: the cfn class should accept the spinning logger and log info whenever it is waiting on something. * refactor(cli-internal): clean up refactorer operations Split rollback holding stack update into its own operation with a validation that the changeset only adds the placeholder. Split forward holding stack deletion into a separate operation. Remove redundant fetchStackResources calls by deriving physical IDs from blueprint mappings. Move description/header construction into describe callbacks and ResourceMapping construction into execute callbacks. Add Cfn.fetchTemplate method. Remove unused imports. --- Prompt: split holding stack operations, add validation, remove redundant fetches, move descriptions into describe callbacks, add Cfn.fetchTemplate. * refactor(cli-internal): harden refactor workflow for multi-stack moves Add stack-level deduplication to prevent duplicate updates when multiple refactorers target the same stack. Thread targetStackId through buildResourceMappings for better error messages. Rework forward beforeMove to incrementally build holding stack templates by fetching existing state. In rollback, defer template computation into the execute closure and add duplicate-resource detection. Remove non-null assertions on StackResource fields. --- Prompt: commit everything I did. don't run tests. * refactor(cli-internal): improve refactor logging, remove caching, add noop handling Add resource-scoped log prefixes to Cfn operations so each category/resource pair is identifiable in output. Remove StackFacade caching layer so every call fetches fresh state from CloudFormation. Introduce buildNoopOperation and suppress the Implications section when all operations are no-ops. In rollback, skip resources that already exist in the target stack instead of throwing. Reduce max wait time from 3600s to 900s and pre-check destination stack existence to select the correct waiter. --- Prompt: commit everything I did. Don't run tests. just commit. * fix(cli-internal): defer template resolution to execution time in refactor workflow RefactorBlueprint now carries only mappings and stack IDs. Templates are fetched and resolved fresh inside each operation's execute() closure, so sequential refactorers targeting the same stack always see current state. This fixes the stale template bug where the second auth refactorer (user-pool-groups) would operate on a Gen2 template that the first refactorer (cognito) had already mutated. updateSource/updateTarget use plan-time resolved stacks directly (still fresh since they run before any moves). updateSource now accepts mappings to determine if a placeholder is needed. move(), beforeMove() (forward), and afterMove() (rollback) all re-fetch and re-resolve templates at execution time. --- Prompt: defer template resolution to execution time in refactor workflow to fix stale template bug when two Gen1 stacks map to the same Gen2 stack. * refactor(cli-internal): move template manipulation into Cfn.refactor and use SDK ResourceMapping Cfn.refactor() now accepts ResourceMapping[] directly, fetches both stack templates, moves resources between them, and handles the full refactor lifecycle internally. This eliminates template manipulation from callers entirely. Replace custom MoveMapping with the SDK's ResourceMapping type throughout the workflow. Simplify move(), beforeMove() (forward), and afterMove() (rollback) to just pass resource mappings. Remove fetchHoldingStackTemplate, isPlaceholderOnlyChangeSet, and the holding stack changeset validation. Move placeholder logic into addPlaceHolderIfNeeded() at the top of plan(). Fix symmetricDifference check to compare .size === 0. --- Prompt: Read what i've done and commit it. * refactor(cli-internal): use SDK ResourceMapping and strip all DependsOn Replace custom MoveMapping with the SDK ResourceMapping type. Cfn.refactor() now accepts ResourceMapping[] directly, fetches both stack templates internally, and moves resources between them before calling the refactor API. Simplify resolveDependencies to unconditionally strip all DependsOn from templates. DependsOn only controls deployment ordering which is irrelevant during refactor since all resources already exist. This also eliminates the partial-view problem where each refactorer only resolved dependencies for its own resource types. Remove resourceIds computation from resolveSource/resolveTarget since resolveDependencies no longer needs it. --- Prompt: use SDK ResourceMapping, move template manipulation into Cfn.refactor, strip all DependsOn unconditionally. * fix(cli-internal): handle absent holding stacks and defer template fetch in rollback Check target stack existence before fetching its template in Cfn.refactor(). Use an empty holding template when the target stack doesn't exist yet (only holding stacks may be absent). Defer holdingTemplate fetch into the execute closure in rollback afterMove so it reads fresh state. Improve error messages to show resource spec instead of class name. --- Prompt: I've made changes. Commit. * refactor(cli-internal): share Cfn instance, enable rollback resolution, add resource logging Share a single Cfn instance across all refactorers. Move update dedup from StackFacade into the workflow: updateSource/updateTarget check cfn.isUpdateClaimed() and call cfn.claimUpdate() at plan time to prevent duplicate operations in the plan. Enable resolveSource/resolveTarget and updateSource/updateTarget in rollback (previously skipped). This fixes the Fn::GetAtt dangling reference error when rolling back after a Gen2 redeploy. Thread DiscoveredResource into Cfn.update(), refactor(), and deleteStack() for resource-scoped log prefixes. --- Prompt: share Cfn instance, enable rollback resolution, add resource logging, plan-time update dedup. * test(cli-internal): update refactor tests for new interfaces Update all refactor test files to match the new API: SDK ResourceMapping instead of MoveMapping, slim RefactorBlueprint with only mappings + stack IDs, shared Cfn instance passed to constructors, and resolveDependencies taking no resource IDs. Update rollback plan test to expect updateSource/updateTarget operations (rollback now resolves and updates both stacks). Remove holding-stack.test.ts (module no longer exists). Rewrite build-refactor-templates.test.ts as minimal constant tests since buildBlueprint was removed. Update refactor.md docs to reflect current architecture. --- Prompt: make all the tests compile, update docs. * fix(cli-internal): prevent test hangs with missing mocks and async fixes Add DeleteChangeSetCommand mock to OAuth test. Make testBuildResourceMappings async and await all callers since buildResourceMappings is async. Convert sync throw assertions to async rejects.toThrow. --- Prompt: make sure the test won't hang by configuring all necessary mocks. * test(cli-internal): fix all refactor tests — 17 suites, 92 tests pass Delete tests for removed modules (cfn-stack-updater, cfn-stack-refactor-updater, legacy-custom-resource). Fix category-plan-orchestration constructor calls with shared Cfn. Update rollback assertions to expect no-op when resources already exist in target. Add default DescribeStacksCommand mocks for holding stack lookups. Mock SDK waiters in snapshot tests to avoid 30s polling delays. Handle missing template files in test framework GetTemplateCommand mock. Update snapshot files for DependsOn stripping. Add early return in beforeMove for empty mappings. Replace symmetricDifference with simple every() check in addPlaceHolderIfNeeded. --- Prompt: start running tests and fix what's needed. * docs(cli-internal): update JSDoc for refactor workflow changes Remove stale "Cached" references from StackFacade. Fix class-level JSDoc in CategoryRefactorer and RollbackCategoryRefactorer to match current method names. Add JSDoc to buildNoopOperation, buildResourceMappings, match, targetLogicalId, updateStackClaims, and createInfrastructure. --- Prompt: compare our code against the gen2-migration branch and make all necessary JSDoc changes. * docs(cli-internal): fix remaining JSDoc inaccuracies Fix afterMove JSDoc to not mention holding stack deletion. Fix "resources resources" typo in UserPoolGroups rollback. --- Prompt: do another pass. * test(cli-internal): make CloudFormation mock stateful with template map Replace invocation counter with a _templateForStack map pre-populated from snapshot files. DescribeStacks and GetTemplate now read from the map. CreateStackRefactor writes both stack templates to the map on create. UpdateStack writes the new template body to the map. DescribeStacks throws ValidationError for stacks not in the map, and returns minimal metadata for dynamically created stacks that lack snapshot files. --- Prompt: commit my changes. * test(cli-internal): reorganize refactor tests to mirror source structure Move test files into subdirectories matching the source layout: resolvers/, auth/, workflow/. Merge auth-forward-mapping tests into auth/auth-cognito-forward.test.ts. Merge build-refactor-templates tests into workflow/category-refactorer.test.ts. Split default-resource-mappings tests into the forward and rollback workflow test files. Delete flat test files that were replaced. Update all import paths for the new directory depth. --- Prompt: reorganize refactor tests to mirror source structure. * chore: revert snapshots * fix(cli-internal): clone empty holding template to prevent cross-refactorer leak EMPTY_HOLDING_TEMPLATE was a shared mutable object. When Cfn.refactor() used it as the target template for a new holding stack, it mutated the shared object by adding resources. Subsequent refactorers that also needed a new holding stack would get the already-mutated object, causing auth resources to leak into the storage holding stack. Fix by cloning the constant before use. --- Prompt: inspect snapshot changes and explain auth resources in storage holding stack. * docs: add coding guideline for module-level mutable constants Add "Don't mutate module-level constant objects" to the Mutability section of CODING_GUIDELINES.md. This pattern caused a real bug where EMPTY_HOLDING_TEMPLATE was shared across refactorers and accumulated resources from previous calls. --- Prompt: review session and add needed guidelines. * chore: geo codegen * chore(cli-internal): remove duplicate ResourceMapping, add dictionary words Remove local ResourceMapping interface from category-refactorer and use the SDK type directly. Add refactorer, refactorers, and changeset to the eslint spellcheck dictionary. --- Prompt: remove ResourceMapping interface, add dictionary words. * style(cli-internal): consistent property order in ResourceMapping objects Reorder ResourceMapping properties to StackName before LogicalResourceId for consistency across forward and rollback refactorers. Update snapshot mapping files accordingly. --- Prompt: I've made some more changes - commit. * chore: regen fitness tracker snapshots * chore: update snapshots * refactor(cli-internal): simplify beforeMove/afterMove to take stack ID Replace RefactorBlueprint parameter with gen2StackId string in beforeMove and afterMove. Both methods now fetch templates and build resource mappings independently from the blueprint, reading the actual stack state at plan time. This decouples holding stack operations from the main move mappings. Add info/debug helpers to CategoryRefactorer base class. Move empty-mappings guard from plan() into move(). Add debug logging to beforeMove and afterMove for traceability. Update fitness-tracker generate snapshots for resource naming. --- Prompt: commit my changes. * test(cli-internal): fix tests for beforeMove/afterMove signature change Update beforeMove tests to pass gen2StackId string and mock GetTemplateCommand for Gen2 template fetch. Update afterMove tests to pass gen2StackId string. Update plan orchestration tests for new operation counts (no early no-op return). --- Prompt: run all cli package tests and fix what's needed. * chore: recapture snapshot * chore: update snapshots * docs(cli-internal): update refactor.md for beforeMove/afterMove changes Update flowcharts and plan() lifecycle to reflect that beforeMove and afterMove now independently discover resources from stack templates rather than using blueprint mappings. --- Prompt: run the PR stage from AGENTS.md. * test(cli-internal): add buildResourceMappings edge case tests Add tests for multiple matching targets, empty source, resource already in target (rollback skip), and empty rollback source. Remove unused CFNResource import from category-refactorer test. --- Prompt: add missing buildResourceMappings tests. * test(cli-internal): add targetLogicalId and match tests for all refactorers Add targetLogicalId tests for auth-cognito-rollback, auth-user-pool-groups-rollback, storage-rollback, storage-dynamo-rollback, and analytics-rollback. Add GroupName-based match tests for auth-user-pool-groups-forward. Add forward edge case tests for duplicate targets and ambiguous same-type matching. Fix bare throw in auth-cognito-rollback to use AmplifyError. Remove unused AmplifyError import from storage-dynamo-rollback. --- Prompt: add targetLogicalId and match tests for all refactorers, fix bare throw. * docs(cli-internal): document resource mapping happy and unhappy paths Add Resource Mapping section to refactor.md explaining forward type-based matching with usedTargetIds dedup, rollback targetLogicalId-based mapping, and all error conditions. --- Prompt: explain happy and unhappy paths of building resource mappings in refactor.md. * fix(cli-internal): skip holding stack resources already present in beforeMove beforeMove now checks the holding stack template before building resource mappings. Resources that already exist in the holding stack are skipped to handle re-execution of forward after a partial failure. Fix test mock to return empty template for REVIEW_IN_PROGRESS holding stacks. --- Prompt: fix REVIEW_IN_PROGRESS holding stack test failure. * feat(cli-internal): delete holding stack after rollback if only placeholder remains After moving resources out of the holding stack during rollback, check if only the migration placeholder resource remains. If so, delete the holding stack. This cleanup happens at execution time since each refactorer moves its own resources independently. --- Prompt: commit what I did. * chore: adding generate snapshots * chore: bring back discussions from gen2-migration * chore: update snapshots * chore: update package * fix(cli-internal): align tests with gen2-migration merge changes Three test files were broken after merging the gen2-migration branch: - category-refactorer.test.ts: fetchSourceStackId now uses 'storage' + resourceName as the prefix. Changed resourceName from 'test' to 'avatars' to match the mock's 'storageavatars' logical ID. - backend.generator.test.ts: Removed ensureStorageStack tests since that method was replaced by createDynamoDBStack (which already has its own tests). - dynamodb.generator.test.ts: Constructor now takes a DiscoveredResource instead of a string. Updated two call sites to pass full DiscoveredResource objects. All 125 test suites (716 tests) pass. --- Prompt: I merged code from the gen2-migration branch and now some cli package tests are failing. run and fix. * chore: pre-refactor snapshots * test(cli-internal): update store-locator snapshot for generate Update pre-generate input and regenerate post-generate snapshots to match current codegen output. Changes include environment variable ordering in auth resource, geo resource import ordering, amplify.yml build commands, and package.json metadata. --- Prompt: commit this * chore: update stack naming with geo prefix * fix(cli-internal): mark GeofenceCollection as unsupported for refactor GeofenceCollection resources use Custom::LambdaCallout which cannot be moved via CloudFormation StackRefactor. Mark them as unsupported in assess and throw in forward/rollback. --- Prompt: mark geofence collection as unsupported for refactor and throw error * chore: update yarn.lock Regenerate lockfile after store-locator pre-generate package.json dependency changes. --- Prompt: fix yarn.lock CI failure * chore: update snapshot.ts * chore: test scripts * chore: gen1 test scripts * chore: gen2 script --------- Co-authored-by: Eli Polonsky (AI) <epolon@amazon.com> Co-authored-by: Sai Ray <saisujit@amazon.com>
1 parent bcec882 commit c86f4e5

File tree

189 files changed

+25131
-21
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

189 files changed

+25131
-21
lines changed

amplify-migration-apps/_test-common/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "shared-test-utils",
33
"private": true,
44
"version": "0.0.0",
5+
"type": "module",
56
"dependencies": {
67
"@aws-sdk/client-cognito-identity-provider": "^3.936.0",
78
"aws-amplify": "^6.15.8"

amplify-migration-apps/snapshot.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ function stackNameFromArn(arnOrName: string): string {
128128
return arnOrName;
129129
}
130130

131-
async function downloadRecursive(stackNameOrArn: string, targetDir: string, appId: string, appName: string): Promise<void> {
131+
async function downloadRecursive(stackNameOrArn: string, targetDir: string): Promise<void> {
132132
const stackName = stackNameFromArn(stackNameOrArn);
133133

134134
const template = await fetchTemplate(stackName);
@@ -148,7 +148,7 @@ async function downloadRecursive(stackNameOrArn: string, targetDir: string, appI
148148

149149
const nestedIds = await fetchNestedStacks(stackName);
150150
for (const nestedId of nestedIds) {
151-
await downloadRecursive(nestedId, targetDir, appId, appName);
151+
await downloadRecursive(nestedId, targetDir);
152152
}
153153
}
154154

@@ -165,8 +165,8 @@ async function capturePreRefactor(appName: string, amplifyAppName?: string, gen2
165165
const targetDir = path.resolve(path.join(__dirname, appName, '_snapshot.pre.refactor'));
166166
resetDir(targetDir);
167167

168-
await downloadRecursive(gen2RootStack, targetDir, app.appId!, app.name!);
169-
await downloadRecursive(gen1RootStack, targetDir, app.appId!, app.name!);
168+
await downloadRecursive(gen2RootStack, targetDir);
169+
await downloadRecursive(gen1RootStack, targetDir);
170170
}
171171

172172
async function capturePostRefactor(appName: string, deployedAppPath: string): Promise<void> {
Lines changed: 310 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
# Store Locator (Amplify Gen1)
2+
3+
![](./images/app.png)
4+
5+
A store locator app that displays store locations on an interactive map powered by AWS Amplify Geo and Amazon Location Service. It uses Maps for rendering store locations, Place Index (Location Search) for address search, and Geofence Collections for users to define virtual perimeters around store areas.
6+
7+
## Install Dependencies
8+
9+
```console
10+
npm install
11+
```
12+
13+
## Initialize Environment
14+
15+
```console
16+
amplify init
17+
```
18+
19+
```console
20+
⚠️ For new projects, we recommend starting with AWS Amplify Gen 2, our new code-first developer experience. Get started at https://docs.amplify.aws/react/start/quickstart/
21+
✔ Do you want to continue with Amplify Gen 1? (y/N) · yes
22+
✔ Why would you like to use Amplify Gen 1? · Prefer not to answer
23+
Note: It is recommended to run this command from the root of your app directory
24+
? Enter a name for the project storeLocator
25+
The following configuration will be applied:
26+
27+
Project information
28+
| Name: storeLocator
29+
| Environment: main
30+
| Default editor: Visual Studio Code
31+
| App type: javascript
32+
| Javascript framework: react
33+
| Source Directory Path: src
34+
| Distribution Directory Path: dist
35+
| Build Command: npm run-script build
36+
| Start Command: npm run-script start
37+
38+
? Initialize the project with the above configuration? No
39+
? Enter a name for the environment main
40+
? Choose your default editor: Visual Studio Code
41+
✔ Choose the type of app that you're building · javascript
42+
Please tell us about your project
43+
? What javascript framework are you using react
44+
? Source Directory Path: src
45+
? Distribution Directory Path: dist
46+
? Build Command: npm run-script build
47+
? Start Command: npm run-script start
48+
Using default provider awscloudformation
49+
? Select the authentication method you want to use: AWS profile
50+
51+
For more information on AWS Profiles, see:
52+
https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-profiles.html
53+
54+
? Please choose the profile you want to use default
55+
```
56+
57+
## Add Categories
58+
59+
### Auth
60+
61+
Cognito-based auth using email. Create Cognito user pool groups for Geofences and add post confirmation lambda trigger to add users to the group.
62+
63+
```console
64+
amplify add auth
65+
```
66+
67+
```console
68+
? Do you want to use the default authentication and security configuration? Manual configuration
69+
? Select the authentication/authorization services that you want to use: User Sign-Up, Sign-In, connected with AWS IAM controls (Enables per-user Storage features for i
70+
mages or other content, Analytics, and more)
71+
? Provide a friendly name for your resource that will be used to label this category in the project: (accept default value)
72+
? Enter a name for your identity pool. (accept default value)
73+
? Allow unauthenticated logins? (Provides scoped down permissions that you can control via AWS IAM) No
74+
? Do you want to enable 3rd party authentication providers in your identity pool? No
75+
? Provide a name for your user pool: (accept default value)
76+
? How do you want users to be able to sign in? Email
77+
? Do you want to add User Pool Groups? Yes
78+
? Provide a name for your user pool group: storeLocatorAdmin
79+
? Do you want to add another User Pool Group No
80+
? Sort the user pool groups in order of preference · storeLocatorAdmin
81+
? Do you want to add an admin queries API? No
82+
? Multifactor authentication (MFA) user login options: OFF
83+
? Email based user registration/forgot password: Enabled (Requires per-user email entry at registration)
84+
? Specify an email verification subject: Your verification code
85+
? Specify an email verification message: Your verification code is {####}
86+
? Do you want to override the default password policy for this User Pool? No
87+
? What attributes are required for signing up? Email
88+
? Specify the app's refresh token expiration period (in days): 100
89+
? Do you want to specify the user attributes this app can read and write? No
90+
? Do you want to enable any of the following capabilities? Add User to Group
91+
? Do you want to use an OAuth flow? No
92+
? Do you want to configure Lambda Triggers for Cognito? Yes
93+
? Which triggers do you want to enable for Cognito Post Confirmation
94+
? What functionality do you want to use for Post Confirmation Add User To Group
95+
? Enter the name of the group to which users will be added. · storeLocatorAdmin
96+
```
97+
98+
### Geo - Map
99+
100+
Map resource for displaying store locations using Amazon Location Service.
101+
102+
```console
103+
amplify add geo
104+
```
105+
106+
```console
107+
? Select which capability you want to add: Map (visualize the geospatial data)
108+
✔ Provide a name for the Map: · storeLocatorMap
109+
✔ Restrict access by? · Both
110+
✔ Who can access this Map? · Authorized and Guest users
111+
Must pick at least 1 of 1 options. Selecting all options [storeLocatorAdmin]
112+
Available advanced settings:
113+
- Map style & Map data provider (default: Streets provided by Esri)
114+
115+
✔ Do you want to configure advanced settings? (y/N) · no
116+
```
117+
118+
### Geo - Location Search
119+
120+
Search index for searching places and addresses.
121+
122+
```console
123+
amplify add geo
124+
```
125+
126+
```console
127+
? Select which capability you want to add: Location search (search by places, addresses, coordinates)
128+
✔ Provide a name for the location search index (place index): · storeLocatorSearch
129+
✔ Restrict access by? · Both
130+
✔ Who can access this search index? · Authorized and Guest users
131+
Must pick at least 1 of 1 options. Selecting all options [storeLocatorAdmin]
132+
Available advanced settings:
133+
- Search data provider (default: HERE)
134+
- Search result storage location (default: no result storage)
135+
136+
✔ Do you want to configure advanced settings? (y/N) · no
137+
```
138+
139+
### Geo - Geofence
140+
141+
```console
142+
amplify add geo
143+
```
144+
145+
```console
146+
? Select which capability you want to add: Geofencing (visualize virtual perimeters)
147+
✔ Provide a name for the Geofence Collection: · storeLocatorGeofence
148+
Must pick at least 1 of 1 options. Selecting all options [storeLocatorAdmin]
149+
✔ What kind of access do you want for storeLocatorAdmin users? Select ALL that apply: · Read geofence, Create/Update geofence, Delete geofence, List geofences
150+
```
151+
152+
```console
153+
amplify push
154+
```
155+
156+
```console
157+
Current Environment: main
158+
159+
┌──────────┬──────────────────────────────────────────┬───────────┬───────────────────┐
160+
│ Category │ Resource name │ Operation │ Provider plugin │
161+
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
162+
│ Auth │ storelocatorcff4360f │ Create │ awscloudformation │
163+
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
164+
│ Geo │ storeLocatorMap │ Create │ awscloudformation │
165+
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
166+
│ Auth │ userPoolGroups │ Create │ awscloudformation │
167+
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
168+
│ Function │ storelocatorcff4360fPostConfirmation │ Create │ awscloudformation │
169+
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
170+
│ Geo │ storeLocatorGeofence │ Create │ awscloudformation │
171+
├──────────┼──────────────────────────────────────────┼───────────┼───────────────────┤
172+
│ Geo │ storeLocatorSearch │ Create │ awscloudformation │
173+
└──────────┴──────────────────────────────────────────┴───────────┴───────────────────┘
174+
175+
✔ Are you sure you want to continue? (Y/n) · yes
176+
```
177+
178+
## Publish Frontend
179+
180+
To publish the frontend, leverage the Amplify hosting console. First push everything to the `main` branch:
181+
182+
```console
183+
git add .
184+
git commit -m "feat: gen1"
185+
git push origin main
186+
```
187+
188+
Next, accept all the default values and follow the getting started wizard to connect your repo and branch. Wait for the deployment to finish successfully.
189+
190+
![](./images/hosting-get-started.png)
191+
![](./images/add-main-branch.png)
192+
![](./images/deploying-main-branch.png)
193+
194+
Wait for the deployment to finish successfully.
195+
196+
## Migrating to Gen2
197+
198+
> Based on https://github.com/aws-amplify/amplify-cli/blob/gen2-migration/GEN2_MIGRATION_GUIDE.md
199+
200+
> [!WARNING]
201+
> Migration is not fully supported for this app because the geo category doesn't support refactoring yet.
202+
> This guide ends at the `generate` step.
203+
204+
First install the experimental amplify CLI package that provides the migration commands.
205+
206+
```console
207+
npm install @aws-amplify/cli-internal-gen2-migration-experimental-alpha
208+
```
209+
210+
Now run them:
211+
212+
```console
213+
npx amplify gen2-migration lock
214+
```
215+
216+
```console
217+
git checkout -b gen2-main
218+
npx amplify gen2-migration generate
219+
```
220+
221+
**Edit in `./src/main.tsx`:**
222+
223+
```diff
224+
- import amplifyconfig from './amplifyconfiguration.json';
225+
+ import amplifyconfig from '../amplify_outputs.json';
226+
```
227+
228+
```console
229+
git add .
230+
git commit -m "feat: migrate to gen2"
231+
git push origin gen2-main
232+
```
233+
234+
**Edit in `./amplify/auth/storelocatorcff4360fPostConfirmation/resource.ts`:**
235+
236+
```diff
237+
- memoryMB: 128,
238+
- runtime: 22
239+
+ memoryMB: 512,
240+
+ runtime: 22,
241+
+ resourceGroupName: 'auth'
242+
```
243+
244+
**Edit in `./amplify/auth/storelocatorcff4360fPostConfirmation/index.js`:**
245+
246+
The Gen1 dynamic `require(`./${name}`)` doesn't work with esbuild bundling in the Amplify build pipeline (`Module not found in bundle: ./add-to-group`). Replace with a static import:
247+
248+
```diff
249+
- const moduleNames = process.env.MODULES.split(',');
250+
- /**
251+
- * The array of imported modules.
252+
- */
253+
- const modules = moduleNames.map((name) => require(`./${name}`));
254+
+ import * as addToGroup from './add-to-group';
255+
+
256+
+ const modules = [addToGroup];
257+
```
258+
259+
```diff
260+
- exports.handler = async (event, context) => {
261+
+ export async function handler(event, context) {
262+
```
263+
264+
**Edit in `./amplify/auth/storelocatorcff4360fPostConfirmation/add-to-group.js`:**
265+
266+
```diff
267+
- const {
268+
- CognitoIdentityProviderClient,
269+
- AdminAddUserToGroupCommand,
270+
- GetGroupCommand,
271+
- CreateGroupCommand,
272+
- } = require('@aws-sdk/client-cognito-identity-provider');
273+
+ import {
274+
+ CognitoIdentityProviderClient,
275+
+ AdminAddUserToGroupCommand,
276+
+ GetGroupCommand,
277+
+ CreateGroupCommand,
278+
+ } from '@aws-sdk/client-cognito-identity-provider';
279+
```
280+
281+
```diff
282+
- exports.handler = async (event) => {
283+
+ export const handler = async (event) => {
284+
```
285+
286+
**Edit in `./amplify/auth/resource.ts`:**
287+
288+
```diff
289+
- triggers: {
290+
- postConfirmation: storelocatorcff4360fPostConfirmation
291+
- },
292+
+ triggers: {
293+
+ postConfirmation: storelocatorcff4360fPostConfirmation
294+
+ },
295+
+ access: (allow) => [
296+
+ allow.resource(storelocatorcff4360fPostConfirmation).to([
297+
+ "addUserToGroup",
298+
+ "manageGroups",
299+
+ ]),
300+
+ ],
301+
```
302+
303+
Now connect the `gen2-main` branch to the hosting service:
304+
305+
![](./images/add-gen2-main-branch.png)
306+
![](./images/deploying-gen2-main-branch.png)
307+
308+
Wait for the deployment to finish successfully.
309+
310+
**The guide ends here because the geo category doesn't support refactoring yet.**
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# amplify
2+
.amplify
3+
amplify_outputs*
4+
amplifyconfiguration*
5+
aws-exports*
6+
node_modules
7+
build
8+
dist
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
version: 1
2+
backend:
3+
phases:
4+
build:
5+
commands:
6+
- "# Execute Amplify CLI with the helper script"
7+
- npm ci --cache .npm --prefer-offline
8+
- npx ampx pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID
9+
frontend:
10+
phases:
11+
preBuild:
12+
commands:
13+
- npm install
14+
build:
15+
commands:
16+
- npm run build
17+
artifacts:
18+
baseDirectory: dist
19+
files:
20+
- "**/*"
21+
cache:
22+
paths:
23+
- node_modules/**/*

0 commit comments

Comments
 (0)