Skip to content

Commit

Permalink
Setting up our Serverless infrastructure
Browse files Browse the repository at this point in the history
  • Loading branch information
fwang committed Apr 8, 2020
1 parent 08789dc commit 777bad3
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 6 deletions.
92 changes: 92 additions & 0 deletions resources/cognito-identity-pool.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
Resources:
# The federated identity for our user pool to auth with
CognitoIdentityPool:
Type: AWS::Cognito::IdentityPool
Properties:
# Generate a name based on the stage
IdentityPoolName: ${self:custom.stage}IdentityPool
# Don't allow unathenticated users
AllowUnauthenticatedIdentities: false
# Link to our User Pool
CognitoIdentityProviders:
- ClientId:
Ref: CognitoUserPoolClient
ProviderName:
Fn::GetAtt: [ "CognitoUserPool", "ProviderName" ]

# IAM roles
CognitoIdentityPoolRoles:
Type: AWS::Cognito::IdentityPoolRoleAttachment
Properties:
IdentityPoolId:
Ref: CognitoIdentityPool
Roles:
authenticated:
Fn::GetAtt: [CognitoAuthRole, Arn]

# IAM role used for authenticated users
CognitoAuthRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Principal:
Federated: 'cognito-identity.amazonaws.com'
Action:
- 'sts:AssumeRoleWithWebIdentity'
Condition:
StringEquals:
'cognito-identity.amazonaws.com:aud':
Ref: CognitoIdentityPool
'ForAnyValue:StringLike':
'cognito-identity.amazonaws.com:amr': authenticated
Policies:
- PolicyName: 'CognitoAuthorizedPolicy'
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: 'Allow'
Action:
- 'mobileanalytics:PutEvents'
- 'cognito-sync:*'
- 'cognito-identity:*'
Resource: '*'

# Allow users to invoke our API
- Effect: 'Allow'
Action:
- 'execute-api:Invoke'
Resource:
Fn::Join:
- ''
-
- 'arn:aws:execute-api:'
- Ref: AWS::Region
- ':'
- Ref: AWS::AccountId
- ':'
- Ref: ApiGatewayRestApi
- '/*'

# Allow users to upload attachments to their
# folder inside our S3 bucket
- Effect: 'Allow'
Action:
- 's3:*'
Resource:
- Fn::Join:
- ''
-
- Fn::GetAtt: [AttachmentsBucket, Arn]
- '/private/'
- '$'
- '{cognito-identity.amazonaws.com:sub}/*'

# Print out the Id of the Identity Pool that is created
Outputs:
IdentityPoolId:
Value:
Ref: CognitoIdentityPool
32 changes: 32 additions & 0 deletions resources/cognito-user-pool.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Resources:
CognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
# Generate a name based on the stage
UserPoolName: ${self:custom.stage}-user-pool
# Set email as an alias
UsernameAttributes:
- email
AutoVerifiedAttributes:
- email

CognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
# Generate an app client name based on the stage
ClientName: ${self:custom.stage}-user-pool-client
UserPoolId:
Ref: CognitoUserPool
ExplicitAuthFlows:
- ADMIN_NO_SRP_AUTH
GenerateSecret: false

# Print out the Id of the User Pool that is created
Outputs:
UserPoolId:
Value:
Ref: CognitoUserPool

UserPoolClientId:
Value:
Ref: CognitoUserPoolClient
17 changes: 17 additions & 0 deletions resources/dynamodb-table.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
Resources:
NotesTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: ${self:custom.tableName}
AttributeDefinitions:
- AttributeName: userId
AttributeType: S
- AttributeName: noteId
AttributeType: S
KeySchema:
- AttributeName: userId
KeyType: HASH
- AttributeName: noteId
KeyType: RANGE
# Set the capacity to auto-scale
BillingMode: PAY_PER_REQUEST
25 changes: 25 additions & 0 deletions resources/s3-bucket.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Resources:
AttachmentsBucket:
Type: AWS::S3::Bucket
Properties:
# Set the CORS policy
CorsConfiguration:
CorsRules:
-
AllowedOrigins:
- '*'
AllowedHeaders:
- '*'
AllowedMethods:
- GET
- PUT
- POST
- DELETE
- HEAD
MaxAge: 3000

# Print out the name of the bucket that is created
Outputs:
AttachmentsBucketName:
Value:
Ref: AttachmentsBucket
27 changes: 21 additions & 6 deletions serverless.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
service: notes-app-api
service: notes-app-2-api

# Create an optimized package for our functions
package:
Expand All @@ -9,20 +9,25 @@ plugins:
- serverless-offline
- serverless-dotenv-plugin # Load .env as environment variables

custom:
# Our stage is based on what is passed in when running serverless
# commands. Or fallsback to what we have set in the provider section.
stage: ${opt:stage, self:provider.stage}
# Set the table name here so we can use it while testing locally
tableName: ${self:custom.stage}-notes

provider:
name: aws
runtime: nodejs12.x
stage: prod
stage: dev
region: us-east-1

# These environment variables are made available to our functions
# under process.env.
environment:
tableName: notes
tableName: ${self:custom.tableName}
stripeSecretKey: ${env:STRIPE_SECRET_KEY}

# 'iamRoleStatements' defines the permission policy for the Lambda function.
# In this case Lambda functions are granted with permissions to access DynamoDB.
iamRoleStatements:
- Effect: Allow
Action:
Expand All @@ -33,7 +38,10 @@ provider:
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: "arn:aws:dynamodb:us-east-1:*:*"
# Restrict our IAM role permissions to
# the specific table for the stage
Resource:
- "Fn::GetAtt": [ NotesTable, Arn ]

functions:
# Defines an HTTP API endpoint that calls the main function in create.js
Expand Down Expand Up @@ -115,3 +123,10 @@ functions:
resources:
# API Gateway Errors
- ${file(resources/api-gateway-errors.yml)}
# DynamoDB
- ${file(resources/dynamodb-table.yml)}
# S3
- ${file(resources/s3-bucket.yml)}
# Cognito
- ${file(resources/cognito-user-pool.yml)}
- ${file(resources/cognito-identity-pool.yml)}

0 comments on commit 777bad3

Please sign in to comment.