DEV Community

Yuva
Yuva

Posted on

Deploying a web app using Lambda, API Gateway, DynamoDB and S3 with Serverless Framework

Step0: Understand the architecture

We are going to use the simplest architecture today to create and deploy a web app.

Step1: Write the app

The app we are creating is a simple idea-board app where anyone can create an idea, add comments, upvote or delete an idea. Find the code for this app in git.

  1. React frontend — Jennifer Peavler created a simple react app.
  2. Backend — A serverless python crud handler.

Serverless backend is written differently compared to traditional server backend.

Lambda needs an entry point and the entry point is a function that takes event, context as arguments.

Step2: Select a deployment method

Principle: Deploy and manage both resources and application code using a version control.

  1. AWS — provides Code Deploy and Code Pipeline to deploy a serverless application using Cloud Formation templates. The templates are used to create stacks that in-turn will manage all the resources specified.

  2. Serverless Framework — provides abstraction over AWS cloud-formation templates. Create a deployment yml file that will generate cloud-formation templates to create stacks that in-turn will manage all the resources specified.

I picked Serverless Framework to deploy our app because

  • Minimum configuration — very easy to manage multiple lambda functions, layers and other related resources.
  • Cloud agnostic — Can be used to deploy to multiple cloud service providers.
  • Widely adopted — Has plenty of plugin support most use-cases
  • Support for local development, stages and rollback

Step3: Write the deployment yml

  1. Start by creating a serverless.yml file and specifying provider requirements.

    service: idea-app-api
    provider:
      name: aws
      runtime: python3.7
      memorySize: 512
     timeout: 30
    
  2. Specify the Lambda function and its triggers. For our app, we have one handler for five types of HTTP triggers.

    functions:
    idea-crud:
    handler:  ideas.handler
    events:
      - http:
          path: ideas
          method: post
          cors: true
      - http:
          path: ideas/{id}
          method: patch
          cors: true
      - http:
          path: ideas/{id}
          method: get
          cors: true
      - http:
          path: ideas/{id}
          method: delete
          cors: true
      - http:
          path: ideas
          method: get
          cors: true
    
  3. Serverless Framwork allows us to specify resources that we can write directly in AWS cloud formation template. For our example, we will create all the needed resources for the database and S3 bucket using serverless.

s3-bucket.yml

  Resources:
  TheBucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: <WEBSITE BUCKET NAME>
      AccessControl: PublicRead
      WebsiteConfiguration:
        IndexDocument: index.html
        ErrorDocument: error.html
  TheBucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: !Ref TheBucket
      PolicyDocument:
        Id: MyPolicy
        Version: '2012-10-17'
        Statement:
          - Sid: PublicReadForGetBucketObjects
            Effect: Allow
            Principal: '*'
            Action: 's3:GetObject'
            Resource: !Join
            - ''
            - - 'arn:aws:s3:::'
              - !Ref TheBucket
              - /*

Complete serverless.yml with S3, dynamo and gateway error resources.

Step4: Deploy!

We have created the resources and the application code. Now it is time to deploy them in AWS. Issue Serverless Framework command to deploy resources. Use --aws-profile option to specify a profile if you have multiple AWS accounts. It will take few mins when you deploy for the first time.

$ >> sls deploy --aws-profile playground                                                                                                                                                      
Serverless: Packaging service...
Serverless: Excluding development dependencies...
Serverless: Creating Stack...
Serverless: Checking Stack create progress...
.....
Serverless: Stack create finished...
Serverless: Uploading CloudFormation file to S3...
Serverless: Uploading artifacts...
Serverless: Uploading service idea-app-api.zip file to S3 (2.5 KB)...
Serverless: Validating template...
Serverless: Updating Stack...
Serverless: Checking Stack update progress...
..................................................................
Serverless: Stack update finished...
Service Information
service: idea-app-api
stage: dev
region: us-east-1
stack: idea-app-api-dev
resources: 22
api keys:
  None
endpoints:
  POST - https://tm0ndmiyt9.execute-api.us-east-1.amazonaws.com/dev/ideas
  PATCH - https://tm0ndmiyt9.execute-api.us-east-1.amazonaws.com/dev/ideas/{id}
  GET - https://tm0ndmiyt9.execute-api.us-east-1.amazonaws.com/dev/ideas/{id}
  DELETE - https://tm0ndmiyt9.execute-api.us-east-1.amazonaws.com/dev/ideas/{id}
  GET - https://tm0ndmiyt9.execute-api.us-east-1.amazonaws.com/dev/ideas
functions:
  idea-crud: idea-app-api-dev-idea-crud
layers:
  None

Serverless successfully created all the resources , deployed our code to Lambda, and created API-Gateway endpoints.

Update the config file (idea-board/app-client/src/config.js) in the frontend to the correct endpoint.

export default {
    apiGateway: {
        REGION: "us-east-1",
        URL: "https://tm0ndmiyt9.execute-api.us-east-1.amazonaws.com/dev"
    }
};

We are almost there! Don’t quit now

Lets push the react app to S3

$ >> npm run build
$ >> aws s3 sync ./build s3://<bucket-name>

Hurray! We did it.

The site is now public and accessible from http://bucket-name.s3-website-us-east-1.amazonaws.com/

Thank you for reading! I would love to receive feedback on my work. Please feel free to comment and let me know how to improve my writing.

Top comments (0)