Serverless

The pros and cons of building a company

without infrastructureย 

Luciano Mammino

1 June 2017, Split

Who is LUCIANO

NeBK20FUA

-20% eBook

ย 

NpBK15FUA

-15% Print

ย 

fancy a coupon? ๐Ÿ˜‡

</ shameless-self-promotion >

Agenda

What is Serverless

History & definition

Advantages & costs

How it Works

Example: AWS Lambda

Example: Serverless Framework

Serverless at Planet 9

Architecture

Security

Quality

Monitoring / Logging

Step Functions

PART 1

What is Serverless

1996 - Let's order few more servers for this rack...

2006 - Let's move the infrastructure in "the cloud"...

2013 - I can "ship" the new API to any VPS as a "container"

TODAY - I ain't got no infrastructure, just code "in the cloud" baby!

The essence of the serverlessย trend is the absence of the server concept during software development.

ย 

โ€” Auth0

Serverless & Serverless.com Framework

๐Ÿ‘จโ€๐Ÿ’ป ย  Focus on business logic, not on infrastructure

๐ŸŽ ย  Virtually โ€œinfiniteโ€ auto-scaling

๐Ÿ’ฐ ย  Pay for invocation / processingย time

Advantages of serverless

Is it cheaper to go serverless?

... It depends

Car analogy

Cars are parked 95% of the time (loige.link/car-parked-95)

How much do you use the car?

Own a car

(Bare metal servers)

Rent a car

(VPS)

City car-sharing

(Serverless)

Less than $0.40/day

for 1 execution/second

What can we build?

๐Ÿ“ฑ ย Mobile Backends

๐Ÿ”Œ ย APIs & Microservices

๐Ÿ“ฆ ย Data Processing pipelines

โšก๏ธ ย Webhooks

๐Ÿค–ย  Bots and integrations

โš™๏ธ ย IoT Backends

๐Ÿ’ป ย Single page web applications

The paradigm

Event โ†’ ๐‘“

IF   ________________________________ 

THEN ________________________________

"IF this THEN that" model

A new CSV file is saved in the object storage

Process it and save it in the DB

HTTP request: GET /products

Retrieve products from DB and return a JSON

It's 2 AM

Scrape weather forecast for next days

Cloud providers

IBM

OpenWhisk

AWS

Lambda

Azure

Functions

Google

Cloud Functions

Auth0

Webtask

Serverless and JavaScript

Frontend

๐ŸŒ Serverless Web hosting is static, but you can build SPAs
(React, Angular, Vue, etc.)

ย 

Backend

๐Ÿ‘Œ Node.js is supported by every provider

โšก๏ธ Fast startup (as opposed to Java)

๐Ÿ“ฆ Use all the modules on NPM

๐Ÿค“ Support other languages/dialects
(TypeScript, ClojureScript, ESNext...)

exports.myLambda = function (
    event,
    context,
    callback
) {

  // get input from event and context

  // use callback to return output or errors

}

Anatomy of a Node.js lambda on AWS

Let's build a "useful"

Hello World API

// write code here

'use strict'

exports.helloWorldHandler = (event, context, callback) => {
  
  const name = 
   (event.queryStringParameters && event.queryStringParameters.name) ?
    event.queryStringParameters.name : 'Split';
    
  const response = {
    statusCode: 200,
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({message: `Hello ${name}`})
  };

  callback(null, response);
};

๐Ÿค™

API Gateway config has been generated for us...

Recap

  1. Login to AWS Dashboard

  2. Create new Lambda from blueprint

  3. Configure API Gateway trigger

  4. Configure Lambda and Security

  5. Write Lambda code

  6. Configure Roles & Publish

โšก๏ธReady!

No local testing ๐Ÿ˜ช ... Manual process ๐Ÿ˜ซ

Enter the...

Get serverless framework

 npm install --global serverless@latest


 sls --help

Create a project

 mkdir helloWorldApi

 cd helloWorldApi

 touch handler.js serverless.yml
// handler.js

'use strict';
exports.helloWorldHandler = (event, context, callback) => {
    const name = 
     (event.queryStringParameters && event.queryStringParameters.name) ?
      event.queryStringParameters.name : 'Split';
    const response = {
      statusCode: 200,
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({message: `Hello ${name}`})
    };
    callback(null, response);
};
# serverless.yml

service: sls-helloWorldApi

provider:
  name: aws
  runtime: "nodejs6.10"

functions:
  helloWorld:
    handler: "handler.helloWorldHandler"
    events:
      - http:
        path: /
        method: get

Local test

touch event.json
{
  "queryStringParameters": {
    "name": "Tim Wagner"
  },
  "httpMethod": "GET",
  "path": "/"
}

Local test

Deploy the lambda

Recap

  1. Install serverless framework

  2. Create handler & serverless config

  3. Test locally (optional)

  4. Deploy

  5. Party hard! ๐Ÿค˜

PART 2

Serverless at Planet 9

a Big Data company

E.g. Meter readings per customer/year

2 ร— 24 ร— 365

Half Hours

ร— 25

~ meter reading points

ร— 24

~ data versions

= ๐Ÿ’ฉloadโ„ข

of data

๐Ÿ‘ฉโ€๐Ÿš€ Limited number of โ€œFull stackโ€ engineers

โšก๏ธ Write & deploy quality code fast

๐Ÿ‘ป Experiment different approaches over different features

๐Ÿ˜Ž Adopt hot and relevant technologies

ย 

Limited number of servers = LIMITED CALLS AT 2 AM!

Why Serverless

Current infrastructure

Serverless land

Web

API & Jobs

Messaging

Serverless

Frontend & Backend

Cloufront & S3

API Gateway & Lambda

planet9energy.io
api.planet9energy.io
Access-Control-Allow-Origin: https://planet9energy.io

CORS HTTP HEADER

ย Custom error page
index.html

Serverless Web Hosting

Serverless APIs

Security: Authentication

"Who is the current user?"

JWT Tokens

Custom
Authorizer Lambda

JWT Token

Authorizer

Login

user: "Podge"
pass: "Unicorns<3"

Users DB

Check
Credentials

JWT token

Validate token & extract userId

API request

API 1

API 2

API 3

Security: Authorization

"Can ย  ย Podge ย  ย trade ย  ย for ย  ย  Account17 ?"

User

Action

Resource

User

Action

Resource

Podge

trade

Account17

Podge

changeSettings

Account17

Luciano

delete

*

...

...

...

Custom ACL module used by every lambda

Built on node-acl & knex.js

Persistence in Postgres

import { can } from '@planet9/acl';

export const tradingHandler =
  async (event, context, callback) => {

  const user = event.requestContext.userId;
  const account = event.pathParameters.accountId;
  const isAuthorized = await can(user, 'trade', account);

  if (!isAuthorized) {
    return callback(new Error('Not Authorized'));
  }

  // ... business logic
}

Security: Sensitive Data

export const handler = (event, context, callback) => {

  const CONN_STRING = process.env.CONN_STRING;

  // ...
}
# serverless.yml

functions:
  myLambda:
    handler: handler.myHandler
    environment:
      CONN_STRING: ${env:CONN_STRING}
  • Split business logic into small testable modules

  • Use dependency injection for external resources
    (DB, Filesystem, etc.)

  • Mock stuff with Jest

  • Aim for 100% coverage

  • Nyan Cat test runners! ๐Ÿ˜ผ

Quality: Unit Tests

  • Use child_process.exec to launch "sls invoke local"

  • Make assertions on the JSON output

  • Test environment simulated with Docker (Postgres, Cassandra, etc.)

  • Some services are hard to test locally (SNS, SQS, S3)

Quality: Functional Tests

๐Ÿ‘จ Git-Flow

  • Feature branches

  • Pushย code
    GitHub -> CI

Quality: Continuous integration

๐Ÿค– CircleCI

  • Lint code (ESlint)

  • Unit tests

  • Build project

  • Functional tests

  • if commit on "master": create deployable artifact

Development / Test / Deployment

Debugging

... How do we debug then

  • console.log... ๐Ÿ˜‘

  • Using the debug module

  • Enable detailed logs only when needed
    (e.g. export DEBUG=tradingCalculations)

Step Functions

  • Coordinate components of distributed applications

  • Orchestrate different AWS Lambdas

  • Visual flows

  • Different execution patterns (sequential, branching, parallel)

Some lessons learned...

๐Ÿš— Think serverless as microservicesย "microfunctions"

โ„๏ธ Cold starts!

๐Ÿšซ Be aware of soft limits

๐Ÿ›  There is still some infrastructure: use proper tools
(Cloudformation, Terraform, ...)

๐Ÿ‘ PROs

๐Ÿ‘

Agility

๐Ÿ‘

Focus on delivering

Business Value

๐Ÿ‘

Auto-scalability

๐Ÿ‘

Managed service

No calls at 2 am...

๐Ÿ‘

Smooth
Learning Curve

๐Ÿ‘

Pay as you go!

๐Ÿ‘Ž CONs

๐Ÿ‘Ž

No live debugging

๐Ÿ‘Ž

Local development & testing

๐Ÿ‘Ž

Service/Functions

Orchestration

๐Ÿ‘Ž

Servers are still there

๐Ÿ‘Ž

lacking

Tooling / Best practices

Should I switch to
SERVERLESS ? ๐Ÿ˜ฑ

Thanks

(special thanks to @katavic_d, @Podgeypoos79, @quasi_modal & @augeva)