Upgrade to Pro — share decks privately, control downloads, hide ads and more …

AWS Lambda with Serverless Framework and Java

Manish Pandit
October 07, 2017

AWS Lambda with Serverless Framework and Java

Serverless is a node.js based framework that makes creating, deploying, and managing serverless functions a breeze. We will use AWS Lambda as our FaaS (Function-as-a-Service) provider, although Serverless supports IBM OpenWhisk and Microsoft Azure as well.

In this session, we will talk about Serverless Applications, and Create and deploy a java-maven based AWS Lambda API. We will also explore the command line interface to manage lambda, which is provided out of the box by serverless framework.

Manish Pandit

October 07, 2017
Tweet

More Decks by Manish Pandit

Other Decks in Technology

Transcript

  1. About Manish Pandit Director of Platform Engineering @Marqeta Twitter :

    @lobster1234 Blog: lobster1234.github.io LinkedIn: in/mpandit
  2. Serverless Serverless is the finest grain abstraction in distributed computing

    100% managed with zero infrastructure concerns Lowest cost compared to Servers and Containers (if designed correctly!)
  3. Why Serverless Ideal fit for microservices architectures - functions have

    limited, well defined scopes Pricing - you pay for what you use No need to worry about infrastructure
  4. AWS Lambda Function as a Service Simple Pricing Model -

    Memory * time Event Sources - DynamoDB, S3, API Gateway, Cloudwatch, SNS... Security via VPC and IAM Roles
  5. Serverless Framework Node.js based CLI Makes working with FaaS much,

    much easier Simple, YAML based configuration abstracts Cloudformation Supports many cloud providers - AWS, OpenWhisk, GCP, Azure Supports stages Popular, feature rich, well documented
  6. Configure AWS - Option 1 bash-3.2$ aws configure AWS Access

    Key ID [****************4MTA]: AWS Secret Access Key [****************g2uU]: Default region name [us-east-1]: Default output format [json]: bash-3.2$
  7. Configure AWS - Option 2 bash-3.2$ serverless config credentials --provider

    aws --key XXXX --secret YYY If you already have a default profile…. Serverless: Setting up AWS... Serverless: Failed! ~/.aws/credentials already has a "default" profile. Use the overwrite flag ("-o" or "--overwrite") to force the update
  8. Create a Project bash-3.2$ serverless create --template aws-java-maven Serverless: Generating

    boilerplate... Serverless: Successfully generated boilerplate for template: "aws-java-maven" Serverless: NOTE: Please update the "service" property in serverless.yml with your service name bash-3.2$
  9. The Project Structure bash-3.2$ tree . . ├── pom.xml ├──

    serverless.yml └── src └── main ├── java │ └── com │ └── serverless │ ├── ApiGatewayResponse.java │ ├── Handler.java │ └── Response.java └── resources └── log4j.properties 6 directories, 6 files
  10. serverless.yml service: aws-java-maven # NOTE: update this with your service

    name provider: name: aws runtime: java8 package: artifact: target/hello-dev.jar functions: hello: handler: com.serverless.Handler # The following are a few example events you can configure # NOTE: Please make sure to change your handler code to work with those events # Check the event documentation for details # events: # - http: # path: users/create # method: get
  11. Handler Class package com.serverless; import … public class Handler implements

    RequestHandler<Map<String, Object>, ApiGatewayResponse>
  12. handleRequest Method @Override public ApiGatewayResponse handleRequest(Map<String, Object> input, Context context)

    { BasicConfigurator.configure(); LOG.info("received: " + input); Response responseBody = new Response("Go Serverless v1.x! Your function executed successfully!", input); return ApiGatewayResponse.builder() .setStatusCode(200) .setObjectBody(responseBody) .setHeaders(Collections.singletonMap("X-Powered-By", "AWS Lambda & serverless")) .build(); }
  13. Build bash-3.2$ mvn clean install [INFO] Scanning for projects... [INFO]

    [INFO] ------------------------------------------------------------------------ [INFO] Building hello dev [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ hello --- [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 2.666 s [INFO] Finished at: 2017-10-07T01:34:10-07:00 [INFO] Final Memory: 16M/214M [INFO] ------------------------------------------------------------------------
  14. Deploy bash-3.2$ serverless deploy Serverless: Packaging service... Serverless: Creating Stack...

    Serverless: Checking Stack create progress... Serverless: Stack create finished... Serverless: Uploading CloudFormation file to S3... Serverless: Uploading artifacts... Serverless: Validating template... Serverless: Updating Stack... Serverless: Checking Stack update progress... ............... Serverless: Stack update finished... Service Information service: aws-java-maven stage: dev region: us-east-1 stack: aws-java-maven-dev api keys: None endpoints: None functions: hello: aws-java-maven-dev-hello
  15. Invoke bash-3.2$ serverless invoke -f hello { "statusCode": 200, "body":

    "{\"message\":\"Go Serverless v1.x! Your function executed successfully!\",\"input\":{}}", "headers": { "X-Powered-By": "AWS Lambda & serverless" }, "isBase64Encoded": false } bash-3.2$
  16. Execution 1.An event source generates an event, or a trigger

    2.A new container is spun off or an existing one is reused to launch the runtime 3.The function (script if interpreted language, binary if compiled) is executed 4.The runtime exits
  17. Invoke Local bash-3.2$ serverless invoke local -f hello Serverless: In

    order to get human-readable output, please implement "toString()" method of your "ApiGatewayResponse" object. 0 [main] INFO com.serverless.Handler - received: {} com.serverless.ApiGatewayResponse@77cd7a0 bash-3.2$
  18. Using an HTTP Event Source service: aws-java-maven # NOTE: update

    this with your service name provider: name: aws runtime: java8 package: artifact: target/hello-dev.jar functions: hello: handler: com.serverless.Handler events: - http: path: /hello method: get
  19. Deploy with a new stage! bash-3.2$ serverless deploy --stage prod

    Serverless: Packaging service... Serverless: Creating Stack... Serverless: Checking Stack create progress… Serverless: Updating Stack... Serverless: Checking Stack update progress... Serverless: Stack update finished... Service Information service: aws-java-maven stage: prod region: us-east-1 stack: aws-java-maven-prod api keys: None endpoints: GET - https://f582xxq581.execute-api.us-east-1.amazonaws.com/prod/hello functions: hello: aws-java-maven-prod-hello
  20. Test bash-3.2$ curl https://f582xxq581.execute-api.us-east-1.amazonaws.com/prod/hello {"message":"Go Serverless v1.x! Your function executed

    successfully!","input":{"resource":"/hello","path":"/hello","httpMethod":"GET","headers":{"Accept":"*/*","Cl oudFront-Forwarded-Proto":"https","CloudFront-Is-Desktop-Viewer":"true","CloudFront-Is-Mobile- Viewer":"false","CloudFront-Is-SmartTV-Viewer":"false","CloudFront-Is-Tablet-Viewer":"false","CloudFront- Viewer-Country":"US","Host":"f582xxq581.execute-api.us-east-1.amazonaws.com","User- Agent":"curl/7.51.0","Via":"1.1 3cc911e7eb2df956e3f7c8f27c198a0b.cloudfront.net (CloudFront)","X-Amz-Cf- Id":"rngpB7WCzOt_XnMXzDc0Pv5i9Eq7_ZA1olb08W84xi5Of8Od4VvVVw==","X-Amzn-Trace-Id":"Root=1-59d895b4- 375b518e32e7a6866c80fa0a","X-Forwarded-For":"69.181.73.181, 205.251.214.68","X-Forwarded-Port":"443","X- Forwarded- Proto":"https"},"queryStringParameters":null,"pathParameters":null,"stageVariables":null,"requestContext":{" path":"/prod/hello","accountId":"xxxxxxxxxxxx","resourceId":"07sycy","stage":"prod","requestId":"cab13cdc- ab3c-11e7-b85c- 0fc68f7d77c1","identity":{"cognitoIdentityPoolId":null,"accountId":null,"cognitoIdentityId":null,"caller":nu ll,"apiKey":"","sourceIp":"69.181.73.181","accessKey":null,"cognitoAuthenticationType":null,"cognitoAuthenti cationProvider":null,"userArn":null,"userAgent":"curl/7.51.0","user":null},"resourcePath":"/hello","httpMeth od":"GET","apiId":"f582xxq581"},"body":null,"isBase64Encoded":false}} bash-3.2$
  21. Serverless Logs bash-3.2$ serverless logs -f hello START RequestId: 32c366cc-ab41-11e7-bcba-6f7680b04a52

    Version: $LATEST 2017-10-07 09:23:38 <32c366cc-ab41-11e7-bcba-6f7680b04a52> INFO com.serverless.Handler:20 - received: {} 0 [main] INFO com.serverless.Handler - received: {} END RequestId: 32c366cc-ab41-11e7-bcba-6f7680b04a52 REPORT RequestId: 32c366cc-ab41-11e7-bcba-6f7680b04a52 Duration: 411.34 ms Billed Duration: 500 ms Memory Size: 1024 MB Max Memory Used: 63 MB START RequestId: e41254f3-ab41-11e7-ab1b-750906e00517 Version: $LATEST 2017-10-07 09:28:34 <e41254f3-ab41-11e7-ab1b-750906e00517> INFO com.serverless.Handler:20 - received: {} END RequestId: e41254f3-ab41-11e7-ab1b-750906e00517 REPORT RequestId: e41254f3-ab41-11e7-ab1b-750906e00517 Duration: 9.92 ms Billed Duration: 100 ms Memory Size: 1024 MB Max Memory Used: 63 MB
  22. Serverless Metrics bash-3.2$ serverless metrics -f hello Service wide metrics

    October 6, 2017 2:21 AM - October 7, 2017 2:21 AM Invocations: 4 Throttles: 0 Errors: 0 Duration (avg.): 206.84ms bash-3.2$
  23. Serverless Metrics w/ Stages bash-3.2$ serverless metrics --stage dev -f

    hello hello October 6, 2017 2:29 AM - October 7, 2017 2:29 AM Invocations: 8 Throttles: 0 Errors: 0 Duration (avg.): 120.89ms bash-3.2$ serverless metrics --stage prod -f hello hello October 6, 2017 2:29 AM - October 7, 2017 2:29 AM Invocations: 6 Throttles: 0 Errors: 0 Duration (avg.): 187.97ms
  24. Serverless Info bash-3.2$ serverless info Service Information service: aws-java-maven stage:

    dev region: us-east-1 stack: aws-java-maven-dev api keys: None endpoints: None functions: hello: aws-java-maven-dev-hello
  25. Serverless Info w/Stages bash-3.2$ serverless info --stage prod Service Information

    service: aws-java-maven stage: prod region: us-east-1 stack: aws-java-maven-prod api keys: None endpoints: GET - https://f582xxq581.execute-api.us-east-1.amazonaws.com/prod/hello functions: hello: aws-java-maven-prod-hello bash-3.2$
  26. Remove Stack bash-3.2$ serverless remove Serverless: Getting all objects in

    S3 bucket... Serverless: Removing objects in S3 bucket... Serverless: Removing Stack... Serverless: Checking Stack removal progress... .... Serverless: Stack removal finished… bash-3.2$
  27. Remove Stack w/Stages bash-3.2$ serverless remove --stage prod Serverless: Getting

    all objects in S3 bucket... Serverless: Removing objects in S3 bucket... Serverless: Removing Stack... Serverless: Checking Stack removal progress... ................ Serverless: Stack removal finished… bash-3.2$ curl https://f582xxq581.execute-api.us-east-1.amazonaws.com/prod/hello curl: (35) SSL peer handshake failed, the server most likely requires a client certificate to connect bash-3.2$
  28. Lambda Tips 1. Write your code in a way that

    it can be tested without an event source 2. Lambda cannot execute for longer than 5 minutes 3. Coordinating many Lambdas can be difficult, use AWS Step Functions 4. Do not persist anything on the disk - it may not be available 5. Be aware of cold start - JVM will take a while to start 6. Do not write lambdas for everything - if a service is high throughput, you’re better off with ECS or EC2 given the costs 7. Lambdas can be tied to VPCs and have IAM execution roles 8. Serverless supports API Gateway Proxy Integration by default - everything gets passed to the function