Serverless CLI Integration

This Jovo CLI plugin bundles and deploys your Jovo app code using the Serverless CLI.

Introduction

Serverless is a framework and CLI that makes it easier to deploy your code to various cloud providers.

With this integration for the Jovo CLI, you can use Serverless to upload your src code to providers like AWS with the deploy:code command.

You can find an example on GitHub.

Learn more in the following sections:

Installation

Install the plugin like this:

$ npm install @jovotech/target-serverless

If you haven't installed the official Serverless CLI globally yet, you can do so with the below command. By default, this integration assumes the Serverless CLI version 3. Learn more in the configuration section.

$ npm install -g serverless

Add the plugin to your jovo.project.js project configuration file like this:

const { ProjectConfig } = require('@jovotech/cli');
const { ServerlessCli } = require('@jovotech/target-serverless');
// ...

const project = new ProjectConfig({
  // ...

  plugins: [
    // ...
    new ServerlessCli()
  ],
});

The build:serverless command can then be used to generate a serverless.yaml file for deployment:

# Create serverless.yaml file based on plugin configuration
$ jovo build:serverless

This file can be modified directly or in the jovo.project.js configuration. You can learn more about its structure in the official serverless.yml reference.

The deploy:code command can then be used to bundle the code in the src folder and then deploy it based on the serverless.yml using the Serverless CLI.

# Deploy the code using 'serverless deploy'
$ jovo deploy:code serverless

Depending on the provider you want to deploy to, you may also need to make additional configurations. For example, to get started with AWS, you need to make the following keys accessible:

export AWS_ACCESS_KEY_ID=<your-key-here>
export AWS_SECRET_ACCESS_KEY=<your-secret-key-here>

Learn more about all steps in the configuration and deployment sections.

Configuration

In your jovo.project.js project configuration, you can configure the Serverless CLI plugin. This is the default configuration:

const { ProjectConfig } = require('@jovotech/cli');
const { ServerlessCli } = require('@jovotech/target-serverless');
// ...

const project = new ProjectConfig({
  // ...

  plugins: [
    // ...
    new ServerlessCli({
      service: 'my-jovo-serverless-app',
      frameworkVersion: '3', // Needs to match your Serverless CLI version
      package: {
        artifact: './bundle.zip',
      },
      provider: {
        name: 'aws',
        runtime: 'nodejs12.x',
      },
      functions: {
        handler: {
          handler: 'index.handler',
        },
      },
    })
  ],
});

Make sure that the property "frameworkVersion" matches the version number of your local Serverless installation. Not sure? Find out with the command serverless --version.

When running the build:serverless command, this configuration gets converted into YAML format to generate the serverless.yaml file that is needed for deployment. Learn more about all possible properties in the official serverless.yml reference.

# Create serverless.yaml file based on plugin configuration
$ jovo build:serverless

This is the file that gets generated based on the default configuration:

service: my-jovo-serverless-app
frameworkVersion: "3"
package:
  artifact: ./bundle.zip
provider:
  name: aws
  runtime: nodejs12.x
functions:
  handler:
    handler: index.handler

You can either generate the serverless.yaml once and modify it directly, or update the plugin configuration and generate a new file using the build:serverless command.

There are also additional configurations that may be needed for the deployment process. Learn more about Serverless configuration in their official documentation.

For example, to get started with AWS; you need to make the following keys accessible:

export AWS_ACCESS_KEY_ID=<your-key-here>
export AWS_SECRET_ACCESS_KEY=<your-secret-key-here>

Deployment

After generating a serverless.yaml file using the build:serverless command, you can use the deploy:code command to bundle and deploy your code.

# Deploy the code using 'serverless deploy'
$ jovo deploy:code serverless

# Example: Deploy prod stage
$ jovo deploy:code serverless --stage prod

The command does the following:

  • Bundles the files in src using the npm run bundle:<stage> script and stores it in a bundle directory. The default stage is dev, learn more about staging here).
  • Calls the serverless deploy command, which uses the serverless.yaml configuration file to upload the bundle to a cloud provider.

Examples

AWS

To deploy your Jovo app to AWS Lambda, you can use this example on GitHub.

To enable a URL endpoint for your function, you can add the following property. This is supported by Serverless v3.12.0 and up.

new ServerlessCli({
  // ...
  functions: {
    handler: {
      // ...
      url: true,
    }
  }
}),

You can retrieve the function URL and other information using the serverless info command.

For platforms like Alexa that allow longer response times, you can also increase the timeout, for example:

new ServerlessCli({
  // ...
  functions: {
    handler: {
      // ...
      timeout: 7, // 7 seconds
    }
  }
}),

For DynamoDB, the following permissions need to be added to the configuration:

new ServerlessCli({
  // ...
  provider: {
    // ...
    iam: {
      role: {
        statements: [
          {
            Effect: 'Allow',
            Action: [
              // @see https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Operations.html
              'dynamodb:CreateTable',
              'dynamodb:DescribeTable',
              'dynamodb:Query',
              'dynamodb:Scan',
              'dynamodb:GetItem',
              'dynamodb:PutItem',
              'dynamodb:UpdateItem',
              'dynamodb:DeleteItem',
            ],
            Resource: 'arn:aws:dynamodb:*:*:table/*',
          },
        ],
      },
    },
  },
}),

Troubleshooting

If you run into problems with the CLI integration (for example if it doesn't provide a verbose error message from Serverless), you can also use these two commands separately:

# Bundle code using bundle:<stage> script
# Example: prod stage
$ npm run bundle:prod

# Deploy code using Serverless CLI
$ serverless deploy