-
Notifications
You must be signed in to change notification settings - Fork 197
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
42 changed files
with
18,285 additions
and
7,656 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,11 @@ | |
|
||
This repo is for the serverless backend API that we build over the course of the tutorial. You can find the repo for the frontend React app [here](https://github.com/AnomalyInnovations/serverless-stack-demo-client). And the repo for the tutorial [here](https://github.com/AnomalyInnovations/serverless-stack-com). | ||
|
||
This repo is split into: | ||
|
||
- **services**: [Serverless Framework](https://github.com/serverless/serverless) services | ||
- **infrastructure**: An [SST](https://github.com/serverless-stack/serverless-stack) app | ||
|
||
#### Steps | ||
|
||
To support the different chapters and steps of the tutorial; we use branches to represent the project codebase at the various points. Here is an index of the various chapters and branches in order. | ||
|
@@ -16,26 +21,43 @@ To support the different chapters and steps of the tutorial; we use branches to | |
|
||
To use this repo locally you need to have the [Serverless framework](https://serverless.com) installed. | ||
|
||
``` bash | ||
```bash | ||
$ npm install serverless -g | ||
``` | ||
|
||
Clone this repo and install the NPM packages. | ||
Clone this repo. | ||
|
||
``` bash | ||
```bash | ||
$ git clone https://github.com/AnomalyInnovations/serverless-stack-demo-api | ||
``` | ||
|
||
Head over to the `infrastructure/` directory and install the npm packages. | ||
|
||
``` bash | ||
$ npm install | ||
``` | ||
|
||
Run a single API on local. | ||
And build the SST app. | ||
|
||
``` bash | ||
$ npx sst build | ||
``` | ||
|
||
Then deploy it to your AWS account | ||
|
||
``` bash | ||
$ npx sst deploy | ||
``` | ||
|
||
Then head over to `services/notes/`. And run a single API endpoint locally. | ||
|
||
```bash | ||
$ serverless invoke local --function list --path event.json | ||
``` | ||
|
||
Where, `event.json` contains the request event info and looks something like this. | ||
|
||
``` json | ||
```json | ||
{ | ||
"requestContext": { | ||
"authorizer": { | ||
|
@@ -47,16 +69,16 @@ Where, `event.json` contains the request event info and looks something like thi | |
} | ||
``` | ||
|
||
Finally, run this to deploy to your AWS account. | ||
Finally, run this to deploy to the API to your AWS account. | ||
|
||
``` bash | ||
```bash | ||
$ serverless deploy | ||
``` | ||
|
||
This project refers to an `.env` file for secret environment variables that are not checking in to the repo. Make sure to create one before dpeloying - https://serverless-stack.com/chapters/load-secrets-from-env.html. | ||
The API service refers to an `.env` file for secret environment variables that are not checking in to the repo. Make sure to create one before deploying - https://serverless-stack.com/chapters/load-secrets-from-env.html. | ||
|
||
--- | ||
|
||
This repo is maintained by [Anomaly Innovations](https://anoma.ly); makers of [Seed](https://seed.run) and [Serverless Stack](https://serverless-stack.com). | ||
|
||
[Email]: mailto:[email protected] | ||
[email]: mailto:[email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
|
||
# testing | ||
/coverage | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
|
||
# vim | ||
.*.sw* | ||
|
||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# Getting Started with Serverless Stack Resources | ||
|
||
This project was bootstrapped with [Create Serverless Stack](https://github.com/serverless-stack/serverless-stack). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import * as cdk from "@aws-cdk/core"; | ||
import * as iam from "@aws-cdk/aws-iam"; | ||
import * as cognito from "@aws-cdk/aws-cognito"; | ||
|
||
export default class CognitoAuthRole extends cdk.Construct { | ||
// Public reference to the IAM role | ||
role; | ||
|
||
constructor(scope, id, props) { | ||
super(scope, id); | ||
|
||
const { identityPool } = props; | ||
|
||
// IAM role used for authenticated users | ||
this.role = new iam.Role(this, "CognitoDefaultAuthenticatedRole", { | ||
assumedBy: new iam.FederatedPrincipal( | ||
"cognito-identity.amazonaws.com", | ||
{ | ||
StringEquals: { | ||
"cognito-identity.amazonaws.com:aud": identityPool.ref, | ||
}, | ||
"ForAnyValue:StringLike": { | ||
"cognito-identity.amazonaws.com:amr": "authenticated", | ||
}, | ||
}, | ||
"sts:AssumeRoleWithWebIdentity" | ||
), | ||
}); | ||
this.role.addToPolicy( | ||
new iam.PolicyStatement({ | ||
effect: iam.Effect.ALLOW, | ||
actions: [ | ||
"mobileanalytics:PutEvents", | ||
"cognito-sync:*", | ||
"cognito-identity:*", | ||
], | ||
resources: ["*"], | ||
}) | ||
); | ||
|
||
new cognito.CfnIdentityPoolRoleAttachment( | ||
this, | ||
"IdentityPoolRoleAttachment", | ||
{ | ||
identityPoolId: identityPool.ref, | ||
roles: { authenticated: this.role.roleArn }, | ||
} | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import { CfnOutput } from "@aws-cdk/core"; | ||
import * as iam from "@aws-cdk/aws-iam"; | ||
import * as cognito from "@aws-cdk/aws-cognito"; | ||
import * as sst from "@serverless-stack/resources"; | ||
import CognitoAuthRole from "./CognitoAuthRole"; | ||
|
||
export default class CognitoStack extends sst.Stack { | ||
constructor(scope, id, props) { | ||
super(scope, id, props); | ||
|
||
const { bucketArn } = props; | ||
|
||
const app = this.node.root; | ||
|
||
const userPool = new cognito.UserPool(this, "UserPool", { | ||
selfSignUpEnabled: true, // Allow users to sign up | ||
autoVerify: { email: true }, // Verify email addresses by sending a verification code | ||
signInAliases: { email: true }, // Set email as an alias | ||
}); | ||
|
||
const userPoolClient = new cognito.UserPoolClient(this, "UserPoolClient", { | ||
userPool, | ||
generateSecret: false, // Don't need to generate secret for web app running on browsers | ||
}); | ||
|
||
const identityPool = new cognito.CfnIdentityPool(this, "IdentityPool", { | ||
allowUnauthenticatedIdentities: false, // Don't allow unathenticated users | ||
cognitoIdentityProviders: [ | ||
{ | ||
clientId: userPoolClient.userPoolClientId, | ||
providerName: userPool.userPoolProviderName, | ||
}, | ||
], | ||
}); | ||
|
||
const authenticatedRole = new CognitoAuthRole(this, "CognitoAuthRole", { | ||
identityPool, | ||
}); | ||
|
||
authenticatedRole.role.addToPolicy( | ||
// IAM policy granting users permission to a specific folder in the S3 bucket | ||
new iam.PolicyStatement({ | ||
actions: ["s3:*"], | ||
effect: iam.Effect.ALLOW, | ||
resources: [ | ||
bucketArn + "/private/${cognito-identity.amazonaws.com:sub}/*", | ||
], | ||
}) | ||
); | ||
|
||
// Export values | ||
new CfnOutput(this, "UserPoolId", { | ||
value: userPool.userPoolId, | ||
}); | ||
new CfnOutput(this, "UserPoolClientId", { | ||
value: userPoolClient.userPoolClientId, | ||
}); | ||
new CfnOutput(this, "IdentityPoolId", { | ||
value: identityPool.ref, | ||
}); | ||
new CfnOutput(this, "AuthenticatedRoleName", { | ||
value: authenticatedRole.role.roleName, | ||
exportName: app.logicalPrefixedName("CognitoAuthRole"), | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import { CfnOutput } from "@aws-cdk/core"; | ||
import * as dynamodb from "@aws-cdk/aws-dynamodb"; | ||
import * as sst from "@serverless-stack/resources"; | ||
|
||
export default class DynamoDBStack extends sst.Stack { | ||
constructor(scope, id, props) { | ||
super(scope, id, props); | ||
|
||
const app = this.node.root; | ||
|
||
const table = new dynamodb.Table(this, "Table", { | ||
billingMode: dynamodb.BillingMode.PAY_PER_REQUEST, // Use on-demand billing mode | ||
sortKey: { name: "noteId", type: dynamodb.AttributeType.STRING }, | ||
partitionKey: { name: "userId", type: dynamodb.AttributeType.STRING }, | ||
}); | ||
|
||
// Output values | ||
new CfnOutput(this, "TableName", { | ||
value: table.tableName, | ||
exportName: app.logicalPrefixedName("TableName"), | ||
}); | ||
new CfnOutput(this, "TableArn", { | ||
value: table.tableArn, | ||
exportName: app.logicalPrefixedName("TableArn"), | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import * as cdk from "@aws-cdk/core"; | ||
import * as s3 from "@aws-cdk/aws-s3"; | ||
import * as sst from "@serverless-stack/resources"; | ||
|
||
export default class S3Stack extends sst.Stack { | ||
// Public reference to the S3 bucket | ||
bucket; | ||
|
||
constructor(scope, id, props) { | ||
super(scope, id, props); | ||
|
||
this.bucket = new s3.Bucket(this, "Uploads", { | ||
// Allow client side access to the bucket from a different domain | ||
cors: [ | ||
{ | ||
maxAge: 3000, | ||
allowedOrigins: ["*"], | ||
allowedHeaders: ["*"], | ||
allowedMethods: ["GET", "PUT", "POST", "DELETE", "HEAD"], | ||
}, | ||
], | ||
}); | ||
|
||
// Export values | ||
new cdk.CfnOutput(this, "AttachmentsBucketName", { | ||
value: this.bucket.bucketName, | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import S3Stack from "./S3Stack"; | ||
import CognitoStack from "./CognitoStack"; | ||
import DynamoDBStack from "./DynamoDBStack"; | ||
|
||
// Add stacks | ||
export default function main(app) { | ||
new DynamoDBStack(app, "dynamodb"); | ||
|
||
const s3 = new S3Stack(app, "s3"); | ||
|
||
new CognitoStack(app, "cognito", { bucketArn: s3.bucket.bucketArn }); | ||
} |
Oops, something went wrong.