Page updated Nov 20, 2023

Project structure

Amplify (Gen 2) backends are defined using TypeScript, and enable you to collocate resources depending on their function. For example, you can author a Post Confirmation trigger for Amazon Cognito right next to your auth's resource file.

First, after creating your first Amplify project with npm create amplify@latest, it will contain the scaffolding for Data and Authentication resources:

├── amplify/ │ ├── auth/ │ │ └── resource.ts │ ├── data/ │ │ └── resource.ts │ ├── backend.ts │ └── package.json ├── node_modules/ ├── .gitignore ├── package-lock.json ├── package.json └── tsconfig.json
1├── amplify/
2│ ├── auth/
3│ │ └── resource.ts
4│ ├── data/
5│ │ └── resource.ts
6│ ├── backend.ts
7│ └── package.json
8├── node_modules/
9├── .gitignore
10├── package-lock.json
11├── package.json
12└── tsconfig.json

As your project grows and your backend is built out, the structure of your project may look like the following:

├── amplify/ │ ├── auth/ │ │ ├── custom-message/ │ │ │ ├── custom-message.tsx │ │ │ ├── handler.ts │ │ │ ├── package.json │ │ │ └── resource.ts │ │ ├── post-confirmation.ts │ │ ├── pre-sign-up.ts │ │ ├── resource.ts │ │ └── verification-email.tsx │ ├── data/ │ │ ├── resolvers/ │ │ │ ├── list-featured-posts.ts │ │ │ └── list-top-10-posts.ts │ │ ├── resource.ts │ │ └── schema.ts │ ├── jobs/ │ │ ├── monthly-report/ │ │ │ ├── handler.ts │ │ │ └── resource.ts │ │ ├── process-featured-posts/ │ │ │ ├── handler.py │ │ │ ├── requirements.txt │ │ │ └── resource.ts │ │ └── store-top-10-posts/ │ │ ├── handler.ts │ │ └── resource.ts │ ├── storage/ │ │ ├── photos/ │ │ │ ├── resource.ts │ │ │ └── trigger.ts │ │ └── reports/ │ │ └── resource.ts │ ├── backend.ts │ └── package.json ├── node_modules/ ├── .gitignore ├── package-lock.json ├── package.json └── tsconfig.json
1├── amplify/
2│ ├── auth/
3│ │ ├── custom-message/
4│ │ │ ├── custom-message.tsx
5│ │ │ ├── handler.ts
6│ │ │ ├── package.json
7│ │ │ └── resource.ts
8│ │ ├── post-confirmation.ts
9│ │ ├── pre-sign-up.ts
10│ │ ├── resource.ts
11│ │ └── verification-email.tsx
12│ ├── data/
13│ │ ├── resolvers/
14│ │ │ ├── list-featured-posts.ts
15│ │ │ └── list-top-10-posts.ts
16│ │ ├── resource.ts
17│ │ └── schema.ts
18│ ├── jobs/
19│ │ ├── monthly-report/
20│ │ │ ├── handler.ts
21│ │ │ └── resource.ts
22│ │ ├── process-featured-posts/
23│ │ │ ├── handler.py
24│ │ │ ├── requirements.txt
25│ │ │ └── resource.ts
26│ │ └── store-top-10-posts/
27│ │ ├── handler.ts
28│ │ └── resource.ts
29│ ├── storage/
30│ │ ├── photos/
31│ │ │ ├── resource.ts
32│ │ │ └── trigger.ts
33│ │ └── reports/
34│ │ └── resource.ts
35│ ├── backend.ts
36│ └── package.json
37├── node_modules/
38├── .gitignore
39├── package-lock.json
40├── package.json
41└── tsconfig.json

Backend resources are defined in resource files using the define* helpers:

import { defineAuth } from '@aws-amplify/backend'; export const auth = defineAuth({ loginWith: { email: true } });
1import { defineAuth } from '@aws-amplify/backend';
2
3export const auth = defineAuth({
4 loginWith: {
5 email: true
6 }
7});

After defining backend resources they are set on the backend:

import { defineBackend } from '@aws-amplify/backend'; import { auth } from './auth/resource.js'; import { data } from './data/resource.js'; defineBackend({ auth, data });
1import { defineBackend } from '@aws-amplify/backend';
2import { auth } from './auth/resource.js';
3import { data } from './data/resource.js';
4
5defineBackend({
6 auth,
7 data
8});

Backends can be extended using the AWS Cloud Development Kit (CDK). By leveraging CDK you can build using any AWS service, such as an Amazon S3 bucket that authenticated users have read and write access to. You can get started by installing AWS CDK:

npm add --save-dev aws-cdk-lib
1npm add --save-dev aws-cdk-lib

Depending on the Node.js package manager you are using, you may encounter warnings where it is now unable to resolve the peer dependency version @aws-amplify/backend has on aws-cdk-lib. If you encounter a warning similar to the following, re-install the version specified in the warning text:

npm WARN Could not resolve dependency: npm WARN peer aws-cdk-lib@"~2.103.0" from @aws-amplify/backend@0.4.0 npm WARN node_modules/@aws-amplify/backend npm WARN dev @aws-amplify/backend@"^0.4.0" from the root project
1npm WARN Could not resolve dependency:
2npm WARN peer aws-cdk-lib@"~2.103.0" from @aws-amplify/backend@0.4.0
3npm WARN node_modules/@aws-amplify/backend
4npm WARN dev @aws-amplify/backend@"^0.4.0" from the root project

Using the sample warning text above, you would need to install aws-cdk-lib@2.103.0.

Then add CDK to your backend:

import * as s3 from 'aws-cdk-lib/aws-s3'; import { defineBackend } from '@aws-amplify/backend'; import { auth } from './auth/resource.js'; import { data } from './data/resource.js'; const backend = defineBackend({ auth, data }); // create the bucket and its stack const bucketStack = backend.getStack('BucketStack'); const bucket = new s3.Bucket(bucketStack, 'Bucket', { blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL }); // allow any authenticated user to read and write to the bucket const authRole = backend.resources.auth.resources.authenticatedUserIamRole; bucket.grantReadWrite(authRole); // allow any guest (unauthenticated) user to read from the bucket const unauthRole = backend.resources.auth.resources.unauthenticatedUserIamRole; bucket.grantRead(unauthRole);
1import * as s3 from 'aws-cdk-lib/aws-s3';
2import { defineBackend } from '@aws-amplify/backend';
3import { auth } from './auth/resource.js';
4import { data } from './data/resource.js';
5
6const backend = defineBackend({
7 auth,
8 data
9});
10
11// create the bucket and its stack
12const bucketStack = backend.getStack('BucketStack');
13const bucket = new s3.Bucket(bucketStack, 'Bucket', {
14 blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL
15});
16
17// allow any authenticated user to read and write to the bucket
18const authRole = backend.resources.auth.resources.authenticatedUserIamRole;
19bucket.grantReadWrite(authRole);
20
21// allow any guest (unauthenticated) user to read from the bucket
22const unauthRole = backend.resources.auth.resources.unauthenticatedUserIamRole;
23bucket.grantRead(unauthRole);

Next Steps