Serverless.js

If you did not install before then install serverless.js framework:

npm install -g serverless

You should have finished basic slack setup and have your AWS credentials.

  1. In your terminal go to the sls_app directory you created before: cd sls_app.
  2. Install python requirements plugin: sls plugin install -n serverless-python-requirements
  3. Install AWS pseudo parameters plugin sls plugin install -n serverless-pseudo-parameters
  4. Set environment variables in your terminal (in case you do not know how, check How to set environment variables section:
AWS_ACCESS_KEY_ID=<your key ID>
AWS_SECRET_ACCESS_KEY=<your secret key>
AWS_REGION=eu-west-1
AWS_DEFAULT_REGION=eu-west-1
SLACK_TOKEN=<your BOT token>
SLACK_CHANNEL="<your slack channel ID>"

serverless.yml

We are going to briefly describe serverless.yml file, please visit official page with full description. Most common feature used in our serverless.yml is dynamic variable replacement (reference). Example syntax of variables:

yamlKeyXYZ: ${variableSource}
# this is an example of providing a default value as the second parameter
otherYamlKey: ${variableSource, defaultValue}

There are many variable sources, please see the official documentation for more details.

This file describes our environment (cloud provider), runtime, functions, plugins, other cloud resources and the final package.

serverless.yml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
service: user1

provider:
  name: aws
  runtime: python3.7
  region: eu-west-1
  tags:
    user: ${self:service}
  environment:  # global environment variables available to all functions within the service
    SLACK_CHANNEL: ${env:SLACK_CHANNEL}
    SLACK_TOKEN: ${env:SLACK_TOKEN}
    DYNAMODB_TABLE: ${self:service}
  iamManagedPolicies:
    - "arn:aws:iam::#{AWS::AccountId}:policy/${self:service}-serverless-workshop-policy"
  • service - Provides a namespace for our project

  • provider - Is the environment where are we going to deploy our application (in our case it’s AWS). Some attributes can be set at different scopes service, provider, function. Everything we set within provider scope is common for all functions.

  • provider.iamManagedPolicies - IAM service role with permissions our functions require to run.

    Note: if you are using this lab on your own account, you will need to define your own role similar to this one

serverless.yml
16
17
18
19
package:
  exclude:
    - node_modules/**
    - tests/**
  • package - final zip file uploaded to S3 and deployed to AWS Lambda
serverless.yml
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
functions:
  # Lambda function with Flask application to handle Slack communication
  slack-responses:
    handler: wsgi_handler.handler
    events:
      - http:
          path: actions
          method: post
  # Lambda function triggered by CloudWatch events
  scheduled-events:
    handler: standup_bot/scheduled.lambda_handler
    events:
      - schedule:
          description: 'Send questions'
#          rate: cron(0 8 ? * MON-FRI *)  # Mo-Fri 8:00
          rate: rate(5 minutes)  # For testing
          enabled: false
          inputTransformer:
            inputPathsMap:
              eventTime: "$.time"
              source: "$.source"
            inputTemplate: '{"source": <source>,"time": <eventTime>,"type": "send_questions"}'
      - schedule:
          description: 'Send report.'
#          rate: cron(0 10 ? * MON-FRI *)  # Mo-Fri 10:00
          rate: rate(5 minutes)  # For testing
          enabled: false
          inputTransformer:
            inputPathsMap:
              eventTime: "$.time"
              source: "$.source"
            inputTemplate: '{"source": <source>,"time": <eventTime>,"type": "send_report"}'
  • functions - Properties and settings for AWS Lambda functions.
  • functions.<fn-name>.handler - Path to python module containing lambda_handler function
  • functions.<fn-name>.events - AWS Lambda function triggers
serverless.yml
55
56
57
58
plugins:
  - serverless-python-requirements
  - serverless-pseudo-parameters
  - serverless-wsgi
  • plugins - Serverless.js plugins (some are installed automatically, others must be installed with sls plugin install -n <plugin-name>
serverless.yml
61
62
63
64
65
66
67
68
69
70
custom:
  wsgi:
    app: standup_bot.action_app.app
    pythonBin: python3
  pythonRequirements:
    slim: true
    slimPatternsAppendDefaults: true
    slimPatterns:
      - "**/*.egg-info*"
      - "**/*.dist-info*"
  • custom - Custom variables, which can be referenced as ${self:custom.<variableName>}
serverless.yml
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
resources:
  Resources:
    StandupDynamoDbTable:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        AttributeDefinitions:
          - AttributeName: report_id
            AttributeType: S
          - AttributeName: report_user_id
            AttributeType: S
        KeySchema:
          - AttributeName: report_id
            KeyType: HASH
          - AttributeName: report_user_id
            KeyType: RANGE
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TableName: ${self:provider.environment.DYNAMODB_TABLE}