aws-amplify / amplify-cli

The AWS Amplify CLI is a toolchain for simplifying serverless web and mobile development.
Apache License 2.0
2.82k stars 818 forks source link

How to split Amplify project into multiple stacks. Error - Limit on the number of resources in a single stack operation exceeded #13536

Closed BBopanna closed 9 months ago

BBopanna commented 9 months ago

How did you install the Amplify CLI?

npm

If applicable, what version of Node.js are you using?

v18.17.1

Amplify CLI Version

12.0.3

What operating system are you using?

Mac

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

NO

Describe the bug

We are getting this error on an amplify project - "Limit on the number of resources in a single stack operation exceeded".

Question is simple - How to split Amplify project into multiple stacks. Are there any documentation with references/examples ?

Expected behavior

References/Documentation on - "How to split Amplify project into multiple stacks"

Reproduction steps

Create an amplify project with AppSync GraphyQL API with 50+ entities and add around 6+ custom resource which build around 30 custom resolvers and try to amplify push to get the error - "Limit on the number of resources in a single stack operation exceeded"

Project Identifier

No response

Log output

``` # Put your logs below this line ```

Additional information

No response

Before submitting, please confirm:

ykethan commented 9 months ago

Hey @BBopanna, thank you for reaching out. Currently, GraphQL API does provides support for splitting resolvers into custom named stack; documentation.

BBopanna commented 9 months ago

Thankyou - problem seems to be around large number of custom resources added in amplify cdk - https://docs.amplify.aws/react/build-a-backend/graphqlapi/modify-amplify-generated-resources/#place-appsync-resolvers-in-custom-named-stacks

Is there a way to break custom resources added via amplify cdk into multiple stacks ?

ykethan commented 9 months ago

@BBopanna , it is currently not supported to split the custom resource. From the number of resources provided on custom, the issue may be due to the number of resolvers on the GraphQL API.

BBopanna commented 9 months ago

Is there a way to create a new stack in the cdk part of amplify ?

This documentation talks about it when working entirely using cdk - https://docs.aws.amazon.com/cdk/v2/guide/stack_how_to_create_multiple_stacks.html

Is this possible in cdk part of amplify ?

Also use dependOn (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html) - may be ?

stack1.node.addDependency(stack2)

ykethan commented 9 months ago

@BBopanna tried creating nested and creating a dependOn with a new stack but i have not been able to split the resource.

Examples tried:

const nst = new NestedStack(this, "nstsk", {});
this.node.addDependency(nst);

class NestedStack extends cdk.NestedStack {
  constructor(scope: Construct, id: string, props?: cdk.NestedStackProps) {
    super(scope, id, props);

    // Define resources for the nested stack here
    new cdk.aws_s3.Bucket(this, "MyBucket");
  }
}

push ran into TemplateURL must be a supported URL.

also tried

this.node.addDependency(cdkStack1);

export class cdkStack1 extends cdk.Stack {
  constructor(
    scope: Construct,
    id: string,
    props?: cdk.StackProps,
    amplifyResourceProps?: AmplifyHelpers.AmplifyResourceProps
  ) {
    super(scope, id, props);
    /* Do not remove - Amplify CLI automatically injects the current deployment environment in this input parameter */
    new cdk.CfnParameter(this, "env", {
      type: "String",
      description: "Current Amplify CLI env name",
    });

    const amplifyProjectInfo = AmplifyHelpers.getProjectInfo();
    const sqsQueueResourceNamePrefix = `sqs-queue-stack1test`;
    const queue = new sqs.Queue(this, "sqs-queue-stack1", {
      queueName: `${sqsQueueResourceNamePrefix}-${cdk.Fn.ref("env")}`,
    });
  }
}

If the use case requires creating custom resources, I would suggest Amplify Gen 2 or using pure cdk with Amplify GraphQL API construct as an workaround.

BBopanna commented 9 months ago

Thankyou @ykethan for trying it out and sharing few more valuable resources - We are on Amplify Gen 1 - what are the possible ways we could go about now that you have mentioned that attempting to add new stack in amplify cdk is not working out ? Please advise.

ykethan commented 9 months ago

@BBopanna the workaround would be to limit the resources on amplify push, by removing some of the resources and push; then add them back in and push. From then number of resources provided the push is likely failing on the 50+ GraphQL models as the custom resources are only 6. you could try consolidating the models or temporarily remove some models and push. additionally, you could try creating a pure cdk app to create the custom resources.

BBopanna commented 9 months ago

Thankyou @ykethan, in light of the above road block and intent to break our app into smaller apps/services some questions

  1. Can we have same Cognito for 2 different Amplify envs - with the intent of breaking the app into two amplify apps ?

  2. Can we migrate Amplify from Gen1 to Gen2? Please let us know any known limitations of services in Gen2.

  3. How to eject amplify project to CDK project? Current documentation is too trivial on the same - https://docs.amplify.aws/javascript/tools/cli/usage/export-to-cdk/ it really does not export everything, lot of refactoring!

  4. Can we export the DynamoDB table records of one amplify env and import those records to another amplify env - Production backup and restore? And Can we do the same for Cognito too - back up user credentials and restore ? OR can we link the same Cognito to the new env?

ykethan commented 9 months ago

@BBopanna Amplify Gen 1, does support importing existing auth resources. Refer to https://docs.amplify.aws/javascript/build-a-backend/auth/import-existing-resources/ providing this information. Amplify Gen 2 is currently in developer preview and are exploring a migration guide for when the service is generally available. For exporting and importing data you should be able to use the export to S3 and import from S3 functionality on DynamoDb or build a custom script. additionally, Amplify Gen 1 provides importing existing DynamoDB tables: https://docs.amplify.aws/javascript/build-a-backend/storage/import/ Unfortunately, i dont believe Cognito provides a export functionality but does provide a import functionality. refer to https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-using-import-tool.html for additional information.

BBopanna commented 9 months ago

Thankyou @ykethan .

Why does commenting the resources in custom resources and pushing and the uncommenting and pushing working if we have truly hit a "Limit" problem. Limit should be a limit irrespective of commenting and uncommenting - What is truly happening here ?

Also how can we use entities defined in .graphql of Gen1 in Gen2 (since docs talk about defining entity in code in Gen2) ? hope folks at Amplify dont expect Gen1 clients to refactor/rewrite entirely ?

ykethan commented 9 months ago

@BBopanna Commenting and un-commenting model definitions in your GraphQL schema toggle creation/deletion of underlying resources such as DynamoDB tables and AppSync resolvers for each of the operations. In some cases, auth resolvers are reused to reduce the amount of resources deployed, however this is not necessarily the case with the remaining pipeline resolvers and can inflate the stacks resources beyond the supported limit.

At this time, CloudFormation has a hard limitation of 2500 resources per nested stack and 500 resources per individual stack. Amplify created stacks are all under one root, nested stack is not fully adjustable at this time. Complex GraphQL schema could be simplified to reduce the number of GraphQL resources in use e.g rewriting the schema to have less models. Using escape hatches like overrides and export may help to scale the application beyond the CLI generated architecture.

You may be able to explore AWS CDK/Amplify Gen 2 (currently in public preview) which allows for a more IaC design that permits more freedom. However, these resources are all still under one nested stack, too but we can create new stacks as needed to mitigate this.

BBopanna commented 9 months ago

thankyou @ykethan

ykethan commented 9 months ago

Closing the issue, feel free in reaching out to us again if you require any further assistance.

github-actions[bot] commented 9 months ago

⚠️COMMENT VISIBILITY WARNING⚠️

Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so.

MarlonJD commented 5 months ago

I was getting same error, I have 63 models, 10 functions. I add some models to custom stacks with https://docs.amplify.aws/gen1/flutter/build-a-backend/graphqlapi/modify-amplify-generated-resources/#place-appsync-resolvers-in-custom-named-stacks. and pushed with amplify push --minify. Gen 1 is works perfect now.

But I couldn't found solution on Gen 2