Skip to content

Commit 6cf6e76

Browse files
iliapolo9pace
andauthored
feat: gen2 migration updates (#8596)
* docs: oauth migration guide updates * docs: remove untested providers * docs: tighten language * docs(migration): add custom resource support and --additional-stateful-resource-types option - Update feature matrix: Custom (CDK) now shows migration tool support - Document --additional-stateful-resource-types option in lock, generate, and refactor steps of the migration guide * docs(migration): add retain command and update decommissioning section Replace manual retain instructions with amplify gen2-migration retain command. Clarify that retain only applies to nested stack resources. * docs(migration): restructure post-generate auth section heading * docs(migration): fix broken links --------- Co-authored-by: 9pace <paceben@amazon.com>
1 parent 1277d8f commit 6cf6e76

2 files changed

Lines changed: 130 additions & 15 deletions

File tree

  • src/pages/[platform]/start/migrate-to-gen2

src/pages/[platform]/start/migrate-to-gen2/feature-matrix/index.mdx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,10 @@ If a feature you need is not yet supported, [create a feature request](https://g
6060
| Configure username | Yes | [Yes with CDK](/[platform]/build-a-backend/auth/modify-resources-with-cdk/) | 🟢 |
6161
| Configure email | Yes | Yes | 🟢 |
6262
| Configure phone number | Yes | Yes | 🟢 |
63-
| Facebook | Yes | Yes | 🟠 |
64-
| Google | Yes | Yes | 🟠 |
65-
| Amazon | Yes | [Yes](/[platform]/build-a-backend/auth/concepts/external-identity-providers/) | 🔴 |
66-
| Sign-in with Apple | Yes | [Yes](/[platform]/build-a-backend/auth/concepts/external-identity-providers/) | 🔴 |
63+
| Facebook | Yes | [Yes](/[platform]/build-a-backend/auth/concepts/external-identity-providers/) | 🟢 |
64+
| Google | Yes | [Yes](/[platform]/build-a-backend/auth/concepts/external-identity-providers/) | 🟢 |
65+
| Amazon | Yes | [Yes](/[platform]/build-a-backend/auth/concepts/external-identity-providers/) | 🟢 |
66+
| Sign-in with Apple | Yes | [Yes](/[platform]/build-a-backend/auth/concepts/external-identity-providers/) | 🟢 |
6767
| Add user pool groups | Yes | Yes | 🟢 |
6868
| User pool group preference | Yes | Yes | 🟢 |
6969
| Sign-up attributes | Yes | Yes | 🟢 |
@@ -278,7 +278,7 @@ If you host your frontend separately (S3 + CloudFront, on-prem, etc.), run `npx
278278
| Geo (GeofenceCollection) | Yes | [Yes with custom CDK](/[platform]/build-a-backend/add-aws-services/geo/) | 🟠 |
279279
| Predictions | Yes | No | 🔴 |
280280
| Interactions | Yes | No | 🔴 |
281-
| Custom (CDK) | Yes | [Yes with custom CDK](/[platform]/build-a-backend/add-aws-services/custom-resources/) | 🔴 |
281+
| Custom (CDK) | Yes | [Yes with custom CDK](/[platform]/build-a-backend/add-aws-services/custom-resources/) | 🟢 |
282282
| Custom (CFN) | Yes | [Yes with CfnInclude](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.cloudformation_include.CfnInclude.html) | 🔴 |
283283

284284
</InlineFilter>
@@ -292,7 +292,7 @@ If you host your frontend separately (S3 + CloudFront, on-prem, etc.), run `npx
292292
| Geo | No | No | - |
293293
| Predictions | No | No | - |
294294
| Interactions | No | No | - |
295-
| Custom (CDK) | Yes | [Yes with custom CDK](/[platform]/build-a-backend/add-aws-services/custom-resources/) | 🔴 |
295+
| Custom (CDK) | Yes | [Yes with custom CDK](/[platform]/build-a-backend/add-aws-services/custom-resources/) | 🟢 |
296296
| Custom (CFN) | Yes | [Yes with CfnInclude](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.cloudformation_include.CfnInclude.html) | 🔴 |
297297

298298
</InlineFilter>
@@ -309,7 +309,7 @@ If you host your frontend separately (S3 + CloudFront, on-prem, etc.), run `npx
309309
| Geo (GeofenceCollection) | Yes | [Yes with custom CDK](/[platform]/build-a-backend/add-aws-services/geo/) | 🟠 |
310310
| Predictions | Yes | [Yes with custom CDK](/[platform]/build-a-backend/add-aws-services/predictions/) | 🔴 |
311311
| Interactions | Yes | [Yes with custom CDK](/[platform]/build-a-backend/add-aws-services/interactions/) | 🔴 |
312-
| Custom (CDK) | Yes | [Yes with custom CDK](/[platform]/build-a-backend/add-aws-services/custom-resources/) | 🔴 |
312+
| Custom (CDK) | Yes | [Yes with custom CDK](/[platform]/build-a-backend/add-aws-services/custom-resources/) | 🟢 |
313313
| Custom (CFN) | Yes | [Yes with CfnInclude](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.cloudformation_include.CfnInclude.html) | 🔴 |
314314

315315
</InlineFilter>

src/pages/[platform]/start/migrate-to-gen2/migrate-existing-app/index.mdx

Lines changed: 123 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,13 @@ The migration tool requires the following API actions in addition to the standar
188188
"s3:GetEncryptionConfiguration"
189189
],
190190
"Resource": "*"
191+
},
192+
{
193+
"Effect": "Allow",
194+
"Action": [
195+
"cloudformation:GetResource"
196+
],
197+
"Resource": "*"
191198
}
192199
]
193200
}
@@ -347,6 +354,37 @@ During the migration period your Gen 1 environment should not undergo any change
347354
amplify gen2-migration lock
348355
```
349356

357+
The lock step also sets a `Retain` deletion policy on all stateful resources in your Gen 1 stacks to protect them during migration.
358+
359+
<Accordion title="Custom stateful resource types">
360+
361+
The migration tool maintains a default list of CloudFormation resource types it considers stateful (e.g. `AWS::Cognito::UserPool`, `AWS::S3::Bucket`, `AWS::DynamoDB::Table`). During the lock step, only resources matching these types receive the `Retain` deletion policy.
362+
363+
If your application includes custom resources that contain stateful CloudFormation types not in the default list, you can provide them using the `--additional-stateful-resource-types` option. Create a JSON file with an array of CloudFormation resource type strings:
364+
365+
```json
366+
[
367+
"AWS::Elasticsearch::Domain",
368+
"AWS::RDS::DBInstance"
369+
]
370+
```
371+
372+
Then pass the file path to the lock command:
373+
374+
```bash
375+
amplify gen2-migration lock --additional-stateful-resource-types ./my-stateful-types.json
376+
```
377+
378+
The types you provide are merged with the built-in defaults. This ensures the tool correctly identifies and protects your custom stateful resources.
379+
380+
<Callout info>
381+
382+
You will need to pass the same file to the `generate` and `refactor` commands later.
383+
384+
</Callout>
385+
386+
</Accordion>
387+
350388
Once validated, the following restrictive IAM policy is attached to the root stack:
351389

352390
```json
@@ -387,6 +425,29 @@ amplify gen2-migration generate
387425

388426
This command introspects your deployed Gen 1 CloudFormation stacks and generates the equivalent Gen 2 TypeScript backend definition files, overriding your local `./amplify` directory. The generated code is a starting point — some features require manual edits before deploying (see below).
389427

428+
<Accordion title="Custom stateful resource types">
429+
430+
The migration tool maintains a default list of CloudFormation resource types it considers stateful (e.g. `AWS::Cognito::UserPool`, `AWS::S3::Bucket`, `AWS::DynamoDB::Table`). During code generation, the tool uses this list to produce a `Retain` deletion policy in the Gen 2 CDK code for these resources, ensuring they don't override the deletion policy of the Gen 1 resources after refactoring.
431+
432+
If your application includes custom resources that contain stateful CloudFormation types not in the default list, you can provide them using the `--additional-stateful-resource-types` option. Create a JSON file with an array of CloudFormation resource type strings:
433+
434+
```json
435+
[
436+
"AWS::Elasticsearch::Domain",
437+
"AWS::RDS::DBInstance"
438+
]
439+
```
440+
441+
Then pass the file path to the generate command:
442+
443+
```bash
444+
amplify gen2-migration generate --additional-stateful-resource-types ./my-stateful-types.json
445+
```
446+
447+
The types you provide are merged with the built-in defaults. This ensures the generated Gen 2 code includes retention policies for your custom stateful resources.
448+
449+
</Accordion>
450+
390451
Once successful, clean up and reinstall dependencies to avoid stale resolution artifacts from the Gen 1 dependency tree:
391452

392453
```bash
@@ -437,6 +498,8 @@ If you use the standard `Amplify.configure(...)` call and access resources throu
437498
+ apiName: '<gen2-rest-api-name>',
438499
```
439500

501+
In addition, follow these [instructions](https://docs.amplify.aws/react/build-a-backend/add-aws-services/rest-api/set-up-rest-api/#initialize-amplify-api) to reconfigure your `Amplify` instance based on the outputs structure of Gen2.
502+
440503
**Kinesis** — If your frontend sends analytics events to a Kinesis stream, update the stream name to point to the new Gen 2 stream:
441504

442505
```diff
@@ -500,6 +563,25 @@ See [Secrets](https://docs.amplify.aws/react/build-a-backend/functions/environme
500563

501564
</Callout>
502565

566+
#### Auth
567+
568+
##### External Identity Providers
569+
570+
If your Gen 1 app uses social sign-in (Facebook, Google), the generated `callbackUrls` and `logoutUrls` in `./amplify/auth/resource.ts` are inherited from Gen 1 and reference the Gen 1 Amplify Hosting URLs only. The Gen 2 hosting URL must be added before the Hosted UI will accept sign-ins from the Gen 2 frontend.
571+
572+
The generator emits a comment above each URL list as a reminder. Add the Gen 2 URL to both locations:
573+
574+
```diff
575+
callbackUrls: [
576+
'https://main.<gen1-appId>.amplifyapp.com/',
577+
+ 'https://gen2-main.<gen2-appId>.amplifyapp.com/',
578+
],
579+
```
580+
581+
The top-level `externalProviders.callbackUrls`/`logoutUrls` configure the web client used by the frontend. The `oAuth.callbackUrls`/`logoutUrls` inside `applyEscapeHatches` configure a separate native app clientupdate both if present.
582+
583+
The corresponding redirect URIs in the external provider's developer console must also be updated, after the Gen 2 environment is deployed (see [Configure external identity providers](#configure-external-identity-providers) below).
584+
503585
### Step 5: Deploy
504586

505587
Push the generated Gen 2 code to your repository:
@@ -546,6 +628,14 @@ By default, sandbox creates its own DynamoDB tables and does not share Gen 1 mod
546628

547629
</Accordion>
548630

631+
#### Configure external identity providers
632+
633+
If your app uses social sign-in, the Gen 2 deployment creates a new Cognito User Pool Domain distinct from the Gen 1 one. The external provider's developer console must be updated to accept redirects from the new domain before Hosted UI sign-in will work on the Gen 2 frontend.
634+
635+
Open the [Cognito console](https://console.aws.amazon.com/cognito/), select the user pool owned by your Gen 2 branch, and note the domain under _App integrationDomain_.
636+
637+
Then, add the domain to each external provider's console following the standard [External identity providers](/[platform]/build-a-backend/auth/concepts/external-identity-providers/) guide. You do not need to replace the existing Gen 1 entriesadd the Gen 2 domain alongside them so both environments work during the transition.
638+
549639

550640
### Step 6: Functional Tests (CRITICAL)
551641

@@ -609,6 +699,29 @@ amplify pull --appId <appId> --envName main
609699
amplify gen2-migration refactor --to <gen2-root-stack-name>
610700
```
611701

702+
<Accordion title="Custom stateful resource types">
703+
704+
The migration tool maintains a default list of CloudFormation resource types it considers stateful (e.g. `AWS::Cognito::UserPool`, `AWS::S3::Bucket`, `AWS::DynamoDB::Table`). During refactoring, only resources matching these types are moved from your Gen 1 stacks into Gen 2.
705+
706+
If your application includes custom resources that contain stateful CloudFormation types not in the default list, you can provide them using the `--additional-stateful-resource-types` optionthe same file you used in the [lock step](#step-2-lock). Create a JSON file with an array of CloudFormation resource type strings:
707+
708+
```json
709+
[
710+
"AWS::Elasticsearch::Domain",
711+
"AWS::RDS::DBInstance"
712+
]
713+
```
714+
715+
Then pass the file path to the refactor command:
716+
717+
```bash
718+
amplify gen2-migration refactor --to <gen2-root-stack-name> --additional-stateful-resource-types ./my-stateful-types.json
719+
```
720+
721+
The types you provide are merged with the built-in defaults. This ensures the tool correctly identifies and transfers your custom stateful resources during the refactoring step.
722+
723+
</Accordion>
724+
612725
<Callout info>
613726

614727
After the refactor step, a `.amplify/gen2-migration/refactor.operations/` directory is created containing snapshots of every CloudFormation operation performed — templates, parameters, and resource mappings. These files can help with auditing or troubleshooting and are safe to delete once migration is confirmed successful.
@@ -621,11 +734,13 @@ If the refactor fails or produces undesired results, roll it back:
621734
amplify gen2-migration refactor --to <gen2-root-stack-name> --rollback
622735
```
623736

737+
If you had already completed [Step 8: Post-Refactor](#step-8-post-refactor-critical) before rolling back, re-comment `postRefactor();` in `./amplify/backend.ts` on the `gen2-main` branch and push. The function targets resources that the Gen 2 stack no longer owns after rollback and will fail at synth otherwise.
738+
624739
After rolling back, you will need to unlock the Gen 1 environment and redeploy it to restore normal operation:
625740

626741
```bash
627742
amplify gen2-migration lock --rollback
628-
amplify push
743+
amplify push --force
629744
```
630745

631746
### Step 8: Post-Refactor (CRITICAL)
@@ -651,7 +766,7 @@ Edit `./amplify/backend.ts`:
651766

652767
<Callout info>
653768

654-
This function must remain uncommented permanentlyeven after migration is complete. Commenting it out or removing it will cause deployment failures.
769+
This function must remain uncommented after the refactor is complete. Commenting it out or removing it will cause deployment failures. The only exception is if you subsequently run `refactor --rollback` — see [Step 7](#step-7-refactor).
655770

656771
</Callout>
657772

@@ -689,15 +804,15 @@ The Gen 1 CloudFormation stacks may still contain resources (such as auth trigge
689804
To decommission the Gen 1 stacks:
690805

691806
1. Verify that no users or applications are still accessing the Gen 1 stateless resources by inspecting CloudWatch traffic metrics or your organizational tracking systems.
692-
2. Apply the `Retain` [deletion policy](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html) to all resources in the Gen 1 CloudFormation stacks. This prevents CloudFormation from deleting any physical resources when the stack is removed. You can do this by updating each stack (including nested ones) to set `DeletionPolicy: Retain` on every resource and updating the stacks via the CLI or the CloudFormation console.
693-
3. Manually delete individual stateless resources that are no longer needed (e.g. AppSync APIs, Lambda functions, IAM roles) — verifying each one is safe to remove.
694-
4. Delete the Gen 1 root CloudFormation stack. Since all resources have the `Retain` policy, the stack deletion will only remove the stack metadata without affecting any underlying resources.
807+
2. Apply the `Retain` deletion policy to resources in the Gen 1 nested CloudFormation stacks. This prevents CloudFormation from deleting the retained resources when the root stack is removed. Note that the `retain` command only applies to resources in the nested stacksresources in the root stack itself are not retained.
695808

696-
<Callout info>
809+
```bash
810+
amplify gen2-migration retain
811+
```
697812

698-
We are working on a CLI command to automate the process of retaining all resources in your Gen 1 environment. This section will be updated when it is available.
813+
3. Delete the Gen 1 root CloudFormation stack. Resources in the nested stacks will be retained (orphaned) thanks to the deletion policy applied in the previous step. Resources in the root stack itself will be deleted normally.
814+
4. Manually delete individual orphaned resources that are no longer needed (e.g. AppSync APIs, Lambda functions, IAM roles) — verifying each one is safe to remove.
699815

700-
</Callout>
701816

702817
## Troubleshooting
703818

0 commit comments

Comments
 (0)