Slide 1

Slide 1 text

@tmclaughbos Every seat has a strip of paper with a name and SSH address $ ssh ec2-user@user#.training.serverlessops.io Password: ServerlessRunning1016

Slide 2

Slide 2 text

@tmclaughbos HOUSE KEEPING NOTES • Workshop: • https://github.com/ServerlessOpsIO/serverlessops-workshops/tree/master/ 01-up-and-running • Chat: • https://gitter.im/ServerlessOpsIO/serverlessops-workshops • Serverless Boston: • https://www.meetup.com/Serverless-Boston/

Slide 3

Slide 3 text

@tmclaughbos REQUIREMENTS • Computer with internet connection • SSH client • Command line familiarity • Coding familiarity

Slide 4

Slide 4 text

@tmclaughbos AWS SERVERLESS UP AND RUNNING PRESENTED BY TOM MCLAUGHLIN OF SERVERLESSOPS

Slide 5

Slide 5 text

@tmclaughbos INTRO • Tom McLaughlin • Founder ServerlessOps • Infrastructure Engineer • Twitter: @tmclaughbos / @ServerlessOpsIO • ServerlessOps • DevOps transformation & AWS serverless advisory • Serverless: Focus less on operating cloud infrastructure & more on solving problems • Provide engineering & training services. <= WE’RE AVAILABLE • Objective: Understand how to deploy and manage, as well as create a serverless application. • We’re going to deploy serverless microservices to form a serverless application. • We’ll also build and deploy a serverless microservice from start to finish • Audience Takeaway: Ability to continue exploration on your own.

Slide 6

Slide 6 text

@tmclaughbos TABLE OF CONTENTS • Training environment setup • What is serverless? • What is Serverless Framework? • Introduction to our application • Module 1 • Deploy Services • Debug • Q&A • Module 2 • Create New Service • Write function • Deploy Service • Integrate into application • Q&A

Slide 7

Slide 7 text

@tmclaughbos $ ssh ec2-user@user#.training.serverlessops.io Password: ServerlessRunning1016 $ workshop # inside of container

Slide 8

Slide 8 text

@tmclaughbos Editors • nano • vim

Slide 9

Slide 9 text

@tmclaughbos WHAT IS SERVERLESS? • No servers to manage or provision • Consumption (not capacity) priced • Components scales with usage • Availability and fault tolerance built in

Slide 10

Slide 10 text

@tmclaughbos FUNCTIONS AS A SERVICE (FAAS) Event Function Service •Api Request •Message Received •State Change •Python •Go •JavaScript •Java •C# •PowerShell •Datastore •Queue •Message Bus •3rd Party API

Slide 11

Slide 11 text

@tmclaughbos SERVERLESS USE CASES Frontend Web Applications Backend APIs Data Processing / Your Differentiator

Slide 12

Slide 12 text

@tmclaughbos $ serverless help $ sls help $ npm install -g serverless

Slide 13

Slide 13 text

@tmclaughbos INTRODUCING WILD RYDES

Slide 14

Slide 14 text

@tmclaughbos WILD RYDES SERVER ARCHITECTURE

Slide 15

Slide 15 text

@tmclaughbos WILD RYDES SERVERLESS ARCHITECTURE

Slide 16

Slide 16 text

@tmclaughbos MODULE 1: DEPLOY & RUN

Slide 17

Slide 17 text

@tmclaughbos WILD-RYDES-RIDE-FLEET

Slide 18

Slide 18 text

@tmclaughbos WILD-RYDES

Slide 19

Slide 19 text

@tmclaughbos WILD RYDES APPLICATION How is this relationship setup? • $ serverless deploy • Deploy a serverless service

Slide 20

Slide 20 text

@tmclaughbos START MODULE 1

Slide 21

Slide 21 text

@tmclaughbos NAVIGATE TO SITE & USE

Slide 22

Slide 22 text

@tmclaughbos DEBUG • $ serverless info • Obtain info about a deployed service • $ serverless logs • Tail function logs that have been logged to CloudWatch • $ serverless invoke • Invoke a function directly without using its event source

Slide 23

Slide 23 text

@tmclaughbos Q&A

Slide 24

Slide 24 text

@tmclaughbos MODULE 2: BUILDING A NEW SERVICE

Slide 25

Slide 25 text

@tmclaughbos FEATURE REQUEST • Problem: Our application doesn’t record rides requested/dispatched • Solution: wild-rydes-ride-record { "RideId": "cb4e0e60-9c23-11e8-af29-8a060cb55967", "Unicorn": { "Name": "Bucephalus", "Color": "Golden" }, "RequestTime": "2018-08-09 22:30:18.347888" }

Slide 26

Slide 26 text

@tmclaughbos CREATE NEW PROJECT • $ serverless create • Creates a new service from a template • A template specifically for this workshop has been provided • Editors • nano • vim

Slide 27

Slide 27 text

@tmclaughbos SERVERLESS.YAML # Ride record service service: wild-rydes-ride-record plugins: - serverless-python-requirements custom: stage: "${opt:stage, env:SLS_STAGE, 'dev'}" profile: "${opt:aws-profile, env:AWS_PROFILE, env:AWS_DEFAULT_PROFILE, 'default'}" log_level: "${env:LOG_LEVEL, 'INFO'}" pythonRequirements: dockerizePip: false ddb_table_hash_key: 'RideId' provider: name: aws runtime: python3.6 stage: ${self:custom.stage} profile: ${self:custom.profile} environment: LOG_LEVEL: ${self:custom.log_level} stackTags: x-service: wild-rydes-ride-record x-stack: ${self:service}-${self:provider.stage} iamRoleStatements: - Effect: Allow Action: - dynamodb:PutItem Resource: Fn::GetAtt: - RideRecordTable - Arn functions: PutRideRecord: handler: handlers/put_ride_record.handler description: "Create Ride Record In Table" memorySize: 128 timeout: 30 environment: DDB_TABLE_NAME: Ref: RideRecordTable events: - http: method: POST path: /record resources: Resources: RideRecordTable: Type: AWS::DynamoDB::Table Properties: AttributeDefinitions: - AttributeName: ${self:custom.ddb_table_hash_key} AttributeType: S KeySchema: - AttributeName: ${self:custom.ddb_table_hash_key} KeyType: HASH ProvisionedThroughput: ReadCapacityUnits: 5 WriteCapacityUnits: 5 Outputs: RideRecordUrl: Description: "URL of service" Value: Fn::Join: - "" - - "https://" - Ref: ApiGatewayRestApi - ".execute-api." - Ref: AWS::Region - ".amazonaws.com/${self:custom.stage}" - "/record" Export: Name: "${self:service}-${self:provider.stage}-RideRecordUrl"

Slide 28

Slide 28 text

@tmclaughbos WRITE LAMBDA FUNCTION '''Put ride record''' import json import logging import os import boto3 log_level = os.environ.get('LOG_LEVEL', 'INFO') logging.root.setLevel(logging.getLevelName(log_level)) # type: ignore _logger = logging.getLogger(__name__) # DynamoDB DDB_TABLE_NAME = os.environ.get('DDB_TABLE_NAME') DDB_TABLE_HASH_KEY = os.environ.get('DDB_TABLE_HASH_KEY') dynamodb = boto3.resource('dynamodb') DDT = dynamodb.Table(DDB_TABLE_NAME) def _get_body_from_event(event): '''Get data from event body''' return json.loads(event.get('body')) def _put_ride_record(ride_record): '''Put record item''' DDT.put_item( TableName=DDB_TABLE_NAME, Item=ride_record ) def handler(event, context): '''Function entry''' _logger.debug('Event received: {}'.format(json.dumps(event))) ride_record = _get_body_from_event(event) _put_ride_record(ride_record) resp = { 'statusCode': 201, 'body': json.dumps({'success': True}) } _logger.debug('Response: {}'.format(json.dumps(resp))) return resp

Slide 29

Slide 29 text

@tmclaughbos DEBUG • $ serverless info • Obtain info about a deployed service • $ serverless logs • Tail function logs that have been logged to CloudWatch • $ serverless invoke • Invoke a function directly without using its event source

Slide 30

Slide 30 text

@tmclaughbos UPDATE WILD-RYDES-RIDE-REQUEST • Update serverless.yml • RequestRide needs to know RideRecord endpoint • See how RequestRide finds wild-rydes-ride-fleet for a hint • Update RequestUnicorn to send data to wild-rydes-record-ride

Slide 31

Slide 31 text

@tmclaughbos Q&A

Slide 32

Slide 32 text

@tmclaughbos FEEDBACK https://www.serverlessops.io/feedback