Resources

Add a resources section that contains Resources and Outputs maps to declare the necessary resources and output variables. Let's add Resources:

resources:
Resources:

Add an S3 bucket declaration, where we place all the assets and set WebsiteConfiguration to set the default index file:

RustSlsBucket:
Type: AWS::S3::Bucket
Properties:
BucketName: rust-sls-aws
WebsiteConfiguration:
IndexDocument: index.html

We also have to add a policy to allow these files to be read by an external client, such as a browser:

RustSlsBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: "RustSlsBucket"
PolicyDocument:
Statement:
-
Effect: "Allow"
Principal: "*"
Action:
- "s3:GetObject"
Resource:
Fn::Join:
- ""
-
- "arn:aws:s3:::"
-
Ref: "RustSlsBucket"
- "/*"

The Wild Rydes application is configured to use Cognito with a client to authorize users with their accounts. Let's configure it with the following declaration and activate email confirmations:

RustSlsCognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: RustSls
UsernameAttributes:
- email
AutoVerifiedAttributes:
- email
RustSlsCognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
ClientName: RustSlsWebApp
GenerateSecret: false
UserPoolId:
Ref: "RustSlsCognitoUserPool"

In Chapter 7Reliable Integration with Databases, we used a JSON declaration of a table. You can configure a DynamoDB table using the Serverless Framework as well:

RustSlsDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: Rides
AttributeDefinitions:
- AttributeName: RideId
AttributeType: S
KeySchema:
- AttributeName: RideId
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1

Add a role for our lambda_1 crate:

RustSlsLambdaRole:
Type: AWS::IAM::Role
Properties:
RoleName: RustSlsLambda
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole

And add these policies to this role:

Policies:
- PolicyName: DynamoDBWriteAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- logs:CreateLogGroup
- logs:CreateLogStream
- logs:PutLogEvents
Resource:
- 'Fn::Join':
- ':'
-
- 'arn:aws:logs'
- Ref: 'AWS::Region'
- Ref: 'AWS::AccountId'
- 'log-group:/aws/lambda/*:*:*'
- Effect: Allow
Action:
- dynamodb:PutItem
Resource:
'Fn::GetAtt': [ RustSlsDynamoDBTable, Arn ]

We have to provide write access to the DynamoDB table for this role.

Create an authorizer:

RustSlsApiGatewayAuthorizer:
Type: AWS::ApiGateway::Authorizer
Properties:
Name: RustSls
RestApiId:
Ref: ApiGatewayRestApi
Type: COGNITO_USER_POOLS
ProviderARNs:
- Fn::GetAtt: [ RustSlsCognitoUserPool, Arn ]
IdentitySource: method.request.header.Authorization

Declare the output variables:

Outputs:
RustSlsBucketURL:
Description: "RustSls Bucket Website URL"
Value:
"Fn::GetAtt": [ RustSlsBucket, WebsiteURL ]
RustSlsCognitoUserPoolId:
Description: "RustSls Cognito User Pool ID"
Value:
Ref: "RustSlsCognitoUserPool"
RustSlsCognitoUserPoolClientId:
Description: "RustSls Cognito User Pool Client ID"
Value:
Ref: "RustSlsCognitoUserPoolClient"
RustSlsDynamoDbARN:
Description: "RustSls DynamoDB ARN"
Value:
"Fn::GetAtt": [ RustSlsDynamoDBTable, Arn ]

The last section of this long config declares the folder that the serverless-finch plugin will use to upload:

custom:
client:
bucketName: rust-sls-aws
distributionFolder: assets

As you can see, I used rust-sls-aws as the bucket name, but every S3 bucket needs a unique global name, and you have to replace the bucket name in all the configs to deploy it.