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

AWS Lambda meets Continuous Delivery

AWS Lambda meets Continuous Delivery

Talk by Alex Krause and Andreas Mohrhard
devopscon 2016 - Munich

Ein großer Vorteil von AWS Lambda gegenüber anderen Serverless-Diensten ist die gute Integration in die bestehenden AWS-Dienste. So kann beispielsweise auf eingehende E-Mails über den Simple Notification Service (SNS) ebenso reagiert werden, wie auf neu hochgeladene Dateien in S3. Um davon profitieren zu können, müssen Lambda-Funktionen entsprechend konfiguriert werden. Bei Applikationen jenseits der üblichen Beispiele wird dies schnell sehr komplex und fehleranfällig, umso mehr, wenn die Lambda-Funktionen mit AWS API Gateway über HTTP angesprochen werden. Im Vortrag wird am Beispiel einer Single-Page-Applikation gezeigt, wie man in einem Serverless Backend von unterschiedlichen AWS-Diensten profitieren kann und dabei die Konfiguration der unterschiedlichen Lambda-Funktionen und von AWS API Gateway im Griff behält. Mithilfe von CloudFormation, Apex, Serverless oder Terraform kann all das automatisiert und in einen CI-/CD-Prozess integriert werden. Der Vortrag gibt einen Überblick über die unterschiedlichen Möglichkeiten und zeigt konkrete Lösungen.

Andreas Mohrhard

December 06, 2016
Tweet

More Decks by Andreas Mohrhard

Other Decks in Programming

Transcript

  1. $

  2. $

  3. Ops

  4. Commit stage Compile Unit test Analysis Build Installers Automated acceptance

    testing Automated capacity testing Manual Testing Showcases Exploratory testing Release () CI “keep team in sync and get fast feedback” CD “be confident and get code to production”
  5. Configuration Serverless Build Limits Unit Tests Integration Tests Versioning Rollback

    Stress Testing Events / Triggers Deployment Complex Infrastructure
  6. Pipeline , where to run? ✅ Drone, SnapCI, Travis
 ❗

    need comprehensive rights for AWS , Code{Pipeline,Build}
  7. @Override public LambdaProxyResponse handleRequest(LambdaProxyRequest request, Context context) { val query

    = request.getQueryStringParameters(); List<User> results; if (query != null && query.containsKey("usernames")) { val idAsString = Splitter.on(",").splitToList(query.get("usernames")); val usersForQuery = idAsString.stream() .map(s -> User.builder().username(s).build()) .collect(Collectors.toList()); val userTableKeysAndAttributes = new TableKeysAndAttributes(dynamodbAdapter.userTableName); usersForQuery.forEach( u -> userTableKeysAndAttributes .addHashOnlyPrimaryKey(DynamodbAdapter.UserTable.USERNAME, u.getUsername())); results = dynamodbAdapter.dynamodb .batchGetItem(userTableKeysAndAttributes) .getTableItems().get(dynamodbAdapter.userTableName).stream() .map(dynamodbAdapter ::itemToUser) .collect(toList()); } else { [ ...] } return wrapInResponse(results); }
  8. @Override public LambdaProxyResponse handleRequest(LambdaProxyRequest request, Context c) { val query

    = request.getQueryStringParameters(); List<User> results; if (query != null && query.containsKey("usernames")) { List<User> usersForQuery = extractUsernamesFromQuery(query); results = dynamodbAdapter.retrieveUsers(usersForQuery); } else { results = dynamodbAdapter.retrieveUsers(); } return wrapInResponse(results); }
  9. Integration Tests? ✅ disposable environments
 ✅ LambCI, Serverless Offline Plugin


    ✅ DynamoDBLocal.jar
 
 $ docker run -v "$PWD":/var/task lambci/lambda \
 index.myHandler '{"some": "event"}'
  10. service: serverless-peer-reward provider: name: aws runtime: java8 memorySize: 512 timeout:

    10 stage: dev region: eu-central-1 environment: TBL_PREFIX: ${self:provider.stage}-devopscon iamRoleStatements: - Effect: "Allow" Action: - "dynamodb:*" Resource: "*" package: artifact: target/peer-rewards.jar functions: users: handler: biz.cosee…UserHandler events: - http: path: users method: get cors: true rewards: handler: biz.cosee…RewardHandler events: - http: path: rewards method: any cors: true generate: handler: biz.cosee…RandomRewardHandler events: - schedule: rate: rate(1 minute) enabled: false
  11. What’s the catch? ❗50MB per function
 ❗75GB per region ✅

    careful with dependencies, try ProGuard
 ✅ automate cleanups / just overwrite
 ✅ monitoring artifacts in pipeline