Thanks to visit codestin.com
Credit goes to github.com

Skip to content

AMPLIFY GEN2 WITH MONOREPO ULTIMATE GUIDE - NEXTJS #8382

@mt-snowinch

Description

@mt-snowinch

Amplify Gen 2 Monorepo Configuration Complete Guide

After spending several days banging my head against the wall trying to deploy a monorepo with Amplify Gen 2, I finally managed to get everything working. Along the way, I encountered a series of confusing errors, permission issues, and undocumented quirks that made the process far more complex than it needed to be.

In this guide, I want to share everything I’ve learned — step by step — so you don’t have to go through the same painful trial and error. Whether you’re setting up Amplify Gen 2 in a monorepo for the first time or running into obscure deployment errors, this guide should help you avoid common pitfalls and get your app up and running faster.

Table of Contents

Project Structure

gc-monorepo/
├── apps/
│   └── webapp/                 # Next.js frontend application
│       └── package.json
│       └── ...
├── packages/
│   └── backend/               # Amplify Gen 2 backend
│       └── package.json
│       └── .gitignore
├── package.json               # Root package.json with workspaces
├── turbo.json                 # Turborepo configuration
├── amplify.yml                # Amplify build configuration (global)
└── README.md

Prerequisites

  • A mono-repo with turborepo configuration
  • A package intended to be used as shared backend (packages/backend)
  • A client app (in this case nextjs) that needs the backend. (apps/webapp)

Initialize shared backend

  1. Move inside cd packages/backend
  2. run npx ampx init
  3. This will generate a new folder like below
├── packages/
│   └── backend/
│       ├── amplify
│       │   ├── auth/resource.ts
│       │   └── data/resource.ts
│       │   └── backend.ts
│       │   └── package.json
│       │   └── tsconfig.ts
│       └── package.json
  1. Then run npm install tsx
  2. Create an empty index.html with touch index.html (used just to not throw errors during app deploy)
  3. Check if inside package.json this deps are present:
{
    // ..
    "engines": {
        "node": ">=20"
    },
    //...
    "exports": {
        "./amplify": "./amplify/backend.ts"
    },
    "devDependencies": {
        "@aws-amplify/backend": "^1.16.1",
        "@aws-amplify/backend-cli": "^1.8.0",
        "@types/minimatch": "^6.0.0",
        "aws-cdk-lib": "^2.189.1",
        "constructs": "^10.4.2",
        "esbuild": "^0.25.5",
        "tsx": "^4.20.3",
        "typescript": "^5.8.3"
    },
    "dependencies": {
        "aws-amplify": "^6.15.3"
    }
}

Initialize the webapp project

  1. Move inside apps with cd apps
  2. Create the next app with npx create-next-app@latest --name webapp
  3. Test if the build works turbo run build --filter=webapp
  4. If fails fix the errors, else we are ready to move to next step
  5. Install the backend dependencies needed in webapp: npm install @aws-amplify/backend @aws-amplify/backend-cli tsx lightningcss
  6. Move back to the root of the monorepo and install the last dep. cd ../.. && npm install minmatch@latest

Amplify.yml

To make shure to deploy correctly each project for the monorepo
we need to place the amplify.yml inside the project to override the default configuration proposed by amplify
so:

  1. Move on the monorepo root path monorepo/.
  2. Create the amplify.yml file with touch amplify.yml
  3. Edit the amplify.yml with the following configuration:

In amplify monorepo setup, each app must be deployed with his indipendent configuration.
To say to amplify wich configuration use for each "app" we define the appRoot property
The appRoot of one app must be equal to the subpath defined in Amplify console when creating the app.

version: 1
applications:
  # -- Backend ------------------------------------------------------------
  - backend:
      phases:
        preBuild:
          commands:
            - corepack enable # <--This is important
            - npm ci --include=optional --cache .npm --prefer-offline
        build:
          commands:
            - npx ampx pipeline-deploy --branch $AWS_BRANCH --app-id $AWS_APP_ID # <-- With this comand we deploy the shared backend
    frontend:
      phases:
        build:
          commands:
            - echo "No build step – static hosting of index.html"
      artifacts:
        baseDirectory: .
        files:
          - index.html # <-- this is the placeholder we created before
      cache:
        paths: []
    appRoot: packages/backend # <-- This is the app alias path for backend (used by amplify)
  # -- Web app ------------------------------------------------------------
  - backend:
      phases:
        build:
          commands:
            - echo "No backend build step -> linking to guanchit-backend project"
    frontend:
      phases:
        preBuild:
          commands:
            - corepack enable
            - npm rebuild lightningcss # <-- This is necessary to prevent build error with next
            - npm ci --include=optional --cache .npm --prefer-offline
        build:
          commands:
            - npx turbo run build --filter=@guanchit/webapp # <-- we build the app using turbo configuration
        postBuild:
          commands:
            - echo "npx ampx generate outputs --branch $AWS_BRANCH --app-id $BACKEND_APP_ID" # <-- for now we comment this step cause we dont have the backend app id yet
      artifacts:
        baseDirectory: .next
        files:
          - '**/*'
      cache:
        paths: [
          'node_modules/**/*',
          '../../node_modules/**/*',
          '../../packages/backend/node_modules/**/*',
          '.next/cache/**/*'
        ]
    appRoot: apps/webapp # <-- This is the app alias path for frontend (used by amplify)

[!important] Make shure to remove comments from the .yml before publishing

  • In this case we have the first application (packages/backend) that is the shared backend, with a fake frontend created with the empty index.html
  • Then er have the second application (apps/webapp) that is the real frontend app that uses the shared backend
  • For each app the "RootPath" is the path where each command will be runned.

Connect github

  1. Move to root of your project (monorepo/)
  2. Add and push everything on github

Configure the backend on Amplify Cli

  1. Navigate to AWS Amplify dashboard inside your aws account.
  2. Click on "Create new app"
  3. Under "Deploy your app" select "Github" or your favourite git provider and Click on "Next"
  4. Select your repository eg. "my-monorepo" with "main" as branch
  5. Check the Checkbox "My app is a Monorepo" and write the appDir of the backend (in this case packages/backend)
  6. Rename in "my-backend" and leave empty the "frontend build commands" and "build output folder"
  7. Check the radio "Create and use a new service role" and click on "Next"
  8. Then save and deploy.

Important

  • Once deployed you will see the new app and under the title a string like "App ID: xx8b4ih9qxxxxx"
  • This will deploy the resources, like s3, dynamo, api, auth ecc... inside a cloudformation stack.
  1. Copy the APP ID of the backend already deployed. (This will be used later to deploy the frontend app)
  2. In the home page of the already published app you will see on left a side navigation bar with the option "App Settings"
  3. Expand "App Settings" and click on "IAM Roles"
  4. Copy the part of the service role name starting with AmplifySSRLoggingRole-xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

Configure the webapp (frontend) on Amplify

Before starting we need to update the amplify.yml with the backend APP_ID previously copied.

# -- Web app ------------------------------------------------------------
  - backend:
      ...
    frontend:
      phases:
        ...
        postBuild:
          commands:
            - npx ampx generate outputs --branch $AWS_BRANCH --app-id xx8b4ih9qxxxxx # <-- PASTE HERE

Then commit everything and push it to the main branch. Ready to start the deploy of the app.

  1. Navigate to AWS Amplify dashboard inside your aws account.
  2. Click on "Create new app"
  3. Under "Deploy your app" select "Github" or your favourite git provider and Click on "Next"
  4. Select your repository eg. "my-monorepo" with "main" as branch
  5. Check the Checkbox "My app is a Monorepo" and write the appDir of the webapp (in this case apps/webapp)
  6. Rename in "my-frontend" and leave empty the "frontend build commands" and "build output folder"
  7. Under "Service role" select the radio saying "Use an existing service role" and paste the backend previously copied role (eg.AmplifySSRLoggingRole-xxxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
  8. Then save and deploy.

Final considerations

[!important] what we done is to create an indipendent backend app and connect it throw the command npx ampx generate outputs... To the frontend app. We used the same service role to connect them cause they need to access the same backend entities.

To add a new app connected to the backend repeat the webapp procedure

Author

This guide was created by Manuel Tardivo to help developers set up and deploy monorepo applications using AWS Amplify Gen 2. If you find this guide helpful, please consider giving it a star ⭐️ on GitHub.

Please @aws-amplify improve your docs!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions