AWS Serverless Up And Running

AWS Serverless Up And Running

From the ServerlessOps workshop "AWS Serverless Up And Running"

workshop: https://github.com/ServerlessOpsIO/serverlessops-workshops

24794783b45c456b21ff78d6d8259456?s=128

Tom McLaughlin

October 18, 2018
Tweet

Transcript

  1. @tmclaughbos Every seat has a strip of paper with a

    name and SSH address $ ssh ec2-user@user#.training.serverlessops.io Password: ServerlessRunning1016
  2. @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/
  3. @tmclaughbos REQUIREMENTS • Computer with internet connection • SSH client

    • Command line familiarity • Coding familiarity
  4. @tmclaughbos AWS SERVERLESS UP AND RUNNING PRESENTED BY TOM MCLAUGHLIN

    OF SERVERLESSOPS
  5. @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.
  6. @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
  7. @tmclaughbos $ ssh ec2-user@user#.training.serverlessops.io Password: ServerlessRunning1016 $ workshop # inside

    of container
  8. @tmclaughbos Editors • nano • vim

  9. @tmclaughbos WHAT IS SERVERLESS? • No servers to manage or

    provision • Consumption (not capacity) priced • Components scales with usage • Availability and fault tolerance built in
  10. @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
  11. @tmclaughbos SERVERLESS USE CASES </> </> Frontend Web Applications Backend

    APIs Data Processing / Your Differentiator
  12. @tmclaughbos $ serverless help $ sls help $ npm install

    -g serverless
  13. @tmclaughbos INTRODUCING WILD RYDES

  14. @tmclaughbos WILD RYDES SERVER ARCHITECTURE

  15. @tmclaughbos WILD RYDES SERVERLESS ARCHITECTURE

  16. @tmclaughbos MODULE 1: DEPLOY & RUN

  17. @tmclaughbos WILD-RYDES-RIDE-FLEET

  18. @tmclaughbos WILD-RYDES

  19. @tmclaughbos WILD RYDES APPLICATION How is this relationship setup? •

    $ serverless deploy • Deploy a serverless service
  20. @tmclaughbos START MODULE 1

  21. @tmclaughbos NAVIGATE TO SITE & USE

  22. @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
  23. @tmclaughbos Q&A

  24. @tmclaughbos MODULE 2: BUILDING A NEW SERVICE

  25. @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" }
  26. @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
  27. @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"
  28. @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
  29. @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
  30. @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
  31. @tmclaughbos Q&A

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