Using the Serverless Framework With AWS
Tags: serverless, aws, webdev
Published: 2020-06-18 17:33:29

## What is the Serverless Framework

Serverless Framework consists of two parts: *the open source CLI* and *the dashboard*.

In this post I'll talk about the CLI. The CLI helps you with the following:

1. You can describe your application's resources (functions and other cloud resources, like a database) using the config file called `serverless.yml`
2. The Serverless Framework bundles your code, creates necessary cloud resources (according to `serverless.yml`) and deploys your code to the cloud

## Setting Up a Serverless API Project with TypeScript

To start with Serverless Framework you need to install their CLI. There are multiple ways to do this. Please check the [Getting Started](https://serverless.com/framework/docs/getting-started/) page and pick the way which is most appropriate for you.

I installed it using NPM: `npm i -g serverless`.

The fastest way to create a serverless project is to use the `serverless create` command choosing one of the available project templates. To see the list of available templates run `serverless create --help`.

Since I'm using AWS, Node.js, and TypeScript, I've chosen the `aws-nodejs-typescript` template:

```bash
serverless create --template aws-nodejs-typescript --path my-serverless-ts-app
```

This command generates the initial code for the app in the folder called `my-serverless-ts-app`.

I've got the following files in the generated folder:

```
handler.ts
serverless.yml
package.json
tsconfig.json
webpack.config.js
```

The project uses Webpack to compile and bundle the functions. In particular, it uses the [serverless-webpack](https://github.com/serverless-heaven/serverless-webpack) plugin. To compile TypeScript the project uses [ts-loader](https://github.com/TypeStrong/ts-loader) Webpack loader.

The `serverless.yml` contains the configuration of the project and the necessary AWS resources.

The `provider` section contains the settings of the cloud provider you would like to deploy your functions to (AWS in our case):

```yaml
provider
  name: aws
  runtime: nodejs12.x
  apiGateway:
    minimumCompressionSize: 1024 # Enable gzip compression for responses > 1 KB
  environment:
    AWS_NODEJS_CONNECTION_REUSE_ENABLED: 1
```

The `functions` section contains the information about the functions you would like to deploy:

```yaml
functions:
  hello:
    handler: handler.hello
    events:
      - http:
          method: get
          path: hello
```

We use the `handler` setting to specify the path to the actual function within our project's root directory. Here, we have got the function called "hello" which is processed by the `hello` function which is exported from `./handler.ts`. The `http` part specifies that this function should be invoked by an http GET request with the path `/hello`. Basically, when it will be deployed it will be available through a URL which would look something like this:
`https://tu4zgp10ol.execute-api.your-region.amazonaws.com/some-stage/hello`.

The `custom` section is used to configure plugins and to set some custom settings which you will be able to reference in other parts of your serverless.yml config.

To run the code you should install the dependencies:

```bash
npm install
```

Now you can invoke the `hello` function locally using the `invoke local` command:

```bash
serverless invoke local --function hello
```

## Deploying the Project to AWS

To be able to deploy your functions to AWS you need to grant the necessary access credentials to the Serverless Framework. For this you need to do the following:

**1. Create an AWS account if you do not have one already.** [Sign up for an AWS account](https://serverless.com/framework/docs/providers/aws/guide/credentials#sign-up-for-an-aws-account)

**2. Create the necessary access credentials for the Serverless Framework.** There are a few ways to do this: [Use the Serverless Framework Dashboard to set up an AWS Access Role](https://serverless.com/framework/docs/providers/aws/guide/credentials#leveraging-aws-access-roles-in-the-serverless-framework-dashboard) or [Create AWS access keys](https://serverless.com/framework/docs/providers/aws/guide/credentials#creating-aws-access-keys).

For starting out with Serverless, I have used the second way. I have created an IAM user, enabled _Programmatic access_ for this user and attached the _AdministratorAccess_ permission.

After creating the user take a note of the API key and secret temporarily. You will need them next.

<div class="warning">Please note, that the <strong><em>AdministratorAccess</em> permission grants the Serverless Framework administrative access to your account</strong>. But, for security, it is recommended to limit the access to your account as much as possible. It is better to determine the AWS resources which your app is going to use and grant the necessary access permissions for that resources only (you can create custom permissions for an IAM user).</div>

**3. Configure Serverless Framework to use your AWS API key and secret.** There are two ways to do this:

1. [Export the keys as environment variables](https://serverless.com/framework/docs/providers/aws/guide/credentials#quick-setup) in the shell where you run the Serverless CLI.
2. [Use AWS Profiles](https://serverless.com/framework/docs/providers/aws/guide/credentials#using-aws-profiles).

I prefer the 2nd way.

Once you configure the credentials you will be ready to deploy the project to AWS. In this example Serverless will use the following AWS services:

- **S3** - for uploading and storing the project's code
- **CloudFormation** - for provisioning the necessary resources
- **AWS Lambda** - for hosting the functions
- **API Gateway** - for routing the HTTP requests to the corresponding functions

Later in this article I'm explaining [how the deployment process works](#what-happens-behind-the-scenes-while-deployment).

<div class="warning">
Before deploying please learn about the costs. The AWS Lambda, CloudFormation, API Gateway, and S3 services have generous free tier, so most probably the setup I am describing in this article won't cost anything in the beginning.
</div>

To deploy the functions to the cloud we use the `deploy` command:

```bash
serverless deploy
```

This command outputs the deployment information. The most interesting part is the `endpoints` section. This is where we find the list of HTTP endpoints we can use to invoke the deployed functions:

```
endpoints:
  GET - https://tu4zgp10ol.execute-api.us-east-1.amazonaws.com/dev/hello
```

By default Serverless deploys to the `us-east-1` region. The `dev` word in the endpoint URL is the default deployment stage.

<div class="info">A stage is a named reference to a particular deployment of your project. I have written more about stages in the article called <a href="https://dd.engineering/blog/a-practical-introduction-to-aws-lambda#creating-the-api-route">A Practical Introduction to AWS Lambda</a> (search for the word `stage`).</div>

You can set the region and the stage either in the `serverless.yml` file:

```yaml
provider:
  name: aws
  stage: somestage
  region: us-west-2
```

or in the `deploy` command:

```bash
serverless deploy --stage production --region eu-central-1
```

Once the project is deployed to AWS, and under the condition that you do not modify anything about this project directly through the AWS Console, you should be able to remove it from AWS by running the `remove` command:

```bash
serverless remove
```

Also, like in the `deploy` command, you can remove the app in the specific region and/or stage:

```bash
serverless remove --stage dev --region us-east-1
```

I'd recommend to remove this example deployment to avoid possible costs.

### Useful Links:

- [Create Command](https://serverless.com/framework/docs/providers/aws/cli-reference/create/)
- [Deploy Command](https://serverless.com/framework/docs/providers/aws/cli-reference/deploy/)
- [Invoke Local Command](https://serverless.com/framework/docs/providers/aws/cli-reference/invoke-local/)
- [Remove Command](https://serverless.com/framework/docs/providers/aws/cli-reference/remove/)

## What Happens Behind the Scenes While Deployment

A high level overview. When you hit the deploy command the Serverless Framework creates a _CloudFormation_ template based on your serverless.yml file. It packages your functions into ZIP files, creates a _CloudFormation_ stack in your account and uploads the functions using the AWS S3 service. You can find more details about this process in the [AWS - Deploying - How It Works](https://serverless.com/framework/docs/providers/aws/guide/deploying#how-it-works) guide.

CloudFormation is a service which allows you to describe and provision a set of AWS resources (lambda functions, databases, etc) for your application using a YAML or JSON template. Basically, you create a template where you describe the resources you want and how to configure them. You feed your template to CloudFormation and it provisions the resources according to this template grouping them into an entity called _CloudFormation Stack_. You can inspect your CloudFormation stacks in the AWS Console: [AWS CloudFormation](https://eu-west-1.console.aws.amazon.com/cloudformation/home).

CloudFormation allows you to describe your application's infrastructure as code. Your template code becomes the single source of truth for your application's resources. You can review all the resources used by your app by looking into a single file. You can track the changes to your infrastructure by version-contolling your code. All of this helps to simplify the maintenance of your applications.