## Why am I giving this talk?
* using Lambda since GA release in early 2015
* currently have 32 lambda functions in our production build
* plus infrastructure, configuration, etc.
* deploying through test, pre-production and production
I can share my experiences!
## What is AWS Lambda?
Note:
Check who's used AWS before; security warning if needed
## Functions-As-A-Service
* run code
* in response to events
* to do stuff
* without servers
## Run what code?
* NodeJS 4.3
* Python 2.7
* Java 8
* ...think microservices
Note:
Node 0.10.48 runtime at EOL Oct 2016
## Run what code?
Setup code and an "event handler"
## Run what code?
To give you an idea of the Lambda API
```
exports.handler = function(event, context) {
console.log('Hello', event.name, '!');
}
```
```
from...import...
import...
def handler(event, context):
print('Hello {}!'.format(event['name']))
```
```
package ...
import ...
public class Hello {
public void handler(String name, Context context) {
System.out.println(String.format("Hello %s!", name));
}
}
```
## Events?
A standard interface for
* direct invocation
* notifications
* scheduled triggers
* streams
## To do stuff?
* post to Slack
* implement an API endpoint
* copy records into Elasticsearch
* insert records into a database
* perform a healthcheck
* deploy some stuff
* ... and so on
## Without servers?
* well, sort of
* it runs on servers really
* in containers actually
* you don't manage the servers
* you pay for processing time
Note:
AWS blogs mention containers
## Pricing example
* 1x t2.micro Linux instance
* In us-east-1
* $14.64 per month
Note:
Pricing examples as at July 2016
## Pricing example
* 44,640 invocations per month
* 1.5Gb memory
* 500ms per invocation
= $0.56 per month ($0.000_002_501 per request)
Note:
# of invocations = 1/min/31 days
## Pricing example
Free tiers
* First 750h of t2.micro instance usage
* First 1m Lambda invocations
Note:
744h in a month. 1 free t2.micro per month. 22 Lambdas invoking every minute
## Srsly?
What's the catch?
## Latency
* startup time (esp. JVM)
* once started, may be reused
* not for highly latency-sensitive applications
Note:
Very informal measurement of Clojure Lambda. Cold start 20s, 5.5s of runtime.
Second invocation 900ms. 10th invocation 500ms.
## Timeouts
* must set a timeout, up to 5 mins
* not suitable for potentially long-running tasks
* unless they can be broken down
## Limits
* Subject to AWS limits
* at most 100 running functions
* impacted by other limits
* eg. # of Kinesis partitions limits consuming Lambdas
* limits can be increased on request to AWS
## Lock-in
* [Google Functions (currently Alpha)](https://cloud.google.com/functions/)
* [Azure Functions (currently Preview)](https://azure.microsoft.com/en-gb/services/functions)
* similar but incompatible APIs
Note:
Not just the Lambda APIs - also coupling to the producing/comsuming services like Kinesis for data formats
## Ecosystem Maturity
* or lack thereof
* good practices pending
* comprehensive CLI/CloudFormation support
* immature third-party tooling
* eg. testing, deployment
## It's a Lambda Function's Life
Somewhere in the cloud, an event makes its way towards your new Lambda function...
Note:
Break to console; demo setup for Python hello world
## Before the first event...
* you write your function
* upload it
* set memory, vpc configuration
## When the first event arrives
* your function is deployed
* then, it's run with the event
* so it's slow
* but you can initialize stuff
## When another event arrives...
Your function may already be running, so
* no deployment time
* no init to run
* just run the handler function with the new event
* so it's fast
## Or...
Another container might be deployed
* parallelism
* you blew the container up
* resource reallocation
So it could still be slow
## Fast or Slow?
Surprise! You can't tell beforehand
Under load, expect many more fast invocations than slow ones
Note:
Break to console - demo running hello world cold/hot
## How Slow is Slow?
* time anything from ms to several seconds
* fastest for Python
* marginally slower for NodeJS
* much slower for JVM (start time)
* slowest for other JVM languages (start time + large artifacts)
## If there's an error
The event will be retried
* retry strategy varies by event type
* push invocations retry three times
* pull invocations will retry indefinitely
* thoughtful error handling needed!
* not to mention monitoring...
## Lambda Triggers
What kinds of events can invoke a Lambda function?
## Direct invocation (Push)
* mash the test button
* call InvokeFunction using SDK or CLI
* retries on error twice (three total attempts)
* same retry strategy for all push triggers
## CloudWatch Events (Push)
* enables scheduled invocation
* cron/rate
* specify event content
## API Gateway (Push)
* HTTP APIs
* invoking Lambda functions
* powerful, feature-rich
* slow startup could be an issue
* could be a whole talk on its own
## SNS Notification (Push)
* Simple Notification Service
* pub/sub
* venerable AWS Service
* supports any service producing SNS messages
* S3
* CloudWatch logs/alarms
* CloudFormation
## Kinesis Stream (Pull)
* pull batches of records from Kinesis
* parallelism limited by # shards
* keep retrying indefinitely on error
## DynamoDB Stream (Pull)
* react to writes
* tables and indexes
## Fan-out and Fan-in
* 0..* event sources per Lambda
* 0..* Lambdas per event source
## Multiplexing
Configure several event sources for the same Lambda
Note:
Not sure mutiplexing is the right word
## Recursion
Not calculating Fibonacci sequences!
Note:
Recursion just in memory will be ridiculously faster
## Recursion
Mechanism to break down long-running jobs
![Stateless recursive Lambda](images/lambda-recursive-stateless.png "Stateless recursive Lambda")
* call self asynchronously
* or use stateful intermediary (like Kinesis)
* see /code/recursive-lambda-example.js
Note:
InvokeAsync(fname, arg-as-string) to invoke a function asynchronously. Could use Kinesis to parallelise slower object retrieval step
## Microservices Concerns
* robustness
* performance
Note:
Who's doing microservices?
How big are they?
Why set a timeout less than 5 mins?
How to implement a circuit breaker?
## Environmentally Unfriendly?
What does a Lambda's runtime environment look like?
## You don't have...
* environment variables
* config files
(so Lambdas are 11-factor apps?)
## You do have...
The context object provides
* invoked Lambda function ARN
* request ID
* allocated memory, time remaining, etc.
## configure all the things
* so you wrote the code
* how do you configure it?
Note:
There's no way to configure the same Lambda function in different ways
## Include the Batteries?
* pack config up as part of build and/or deployment
* but then not the same artifact
* does it matter?
## Look it up?
* store config somewhere else (like s3)
* indexed by lambda ARN
* but extra call at runtime
* init+memoize?
## Configure the Trigger?
* include config in the triggering "event"
* might work well for manual invocation
* might mix config with data
* harder to reason about lambda "pipelines"
## Approach 'n'
* your solution here?
* wait for AWS to solve the problem
* see if other providers do better
## Other Operational Concerns
## Automation
* CLI and CloudFormation support
* no CodeDeploy/CodePipeline support
* CRUD functions
* publish versions
* assign aliases
## Aliases and Versions
* publish immutable versions
* point an Alias at a Version
* no downtime
* easy rollback
* sounds great...
## Aliases and Versions?
* complicates automation
* account-global
* logs for aliases get mixed up
* extra stuff to learn
Note:
Cannot reference a version in a different account
## Permissions
* IAM policies and roles
* different for push and pull invocation
* push needs permissions to invoke the function
* Lambda needs permissions to invoke the pull resource
## Testing in the Cloud
* configure Sample Event
* mash the test button
* look at the logs
* beware of side effects
## Testing Locally
* technically straightforward
* harder with Java
* glue code may be tough to unit test usefully
* docker might help (fake-s3, dynamodb-local, etc.)
## State
* no predictable memory
* interesting problems involve remembering stuff
* nearest reliable memory is over the network
* slooooow
* can limit performance and parallelism
## Security
See [Shared Responsibility Model](https://aws.amazon.com/compliance/shared-responsibility-model/)
* Lambda runs in container
* access to invoke Lambda via IAM
* Lambda source code in s3 via IAM
* Lambda access to other AWS resources via IAM
Note:
SRM - AWS manages security of the cloud, customer manages their security in the cloud
## Private resources
* new feature for 2016
* lambdas run in your subnets
* can access private resources
* RDS databases (postgresql, mysql, etc.)
* Redshift
* Elasticsearch
* ElastiCache (redis/memcached)
* etc.
## Private Resources
* can route outbound traffic
* perhaps must route outbound traffic!
* via NAT instances or NAT Gateway
* so, known IPs
* useful for IP whitelisting
Note:
If the Lambda needs to talk to AWS or third-party services, outbound internet access will be needed.
## CloudWatch
* logs
* monitoring
* alerts
## CloudWatch in Practice
Duration for Kinesis-based processor
![Busy message processing Lambda](images/y-7d-x-1s-mt.png "Busy message processing Lambda")
* invocation duration
* average over 5-minute period
## CloudWatch in Practice
RTT and Duration for 3rd-party service healthcheck
![RTT and Duration for 3rd-party service healthcheck](images/y-7d-x-1s-ih-rtt-and-invocation-time.png "RTT and Duration for 3rd-party service healthcheck")
* RTT (Orange)
* invocation duration (Blue)
* maxima over 5-minute period
## The Future
* CodeDeploy/CodePipeline integration?
* competition?
* IOpipe et al.?
* git push master lambda?
## Learn more
* [AWS Lambda documentation](https://aws.amazon.com/documentation/lambda/)
* [AWS Lambda in CloudFormation](http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)
* [AWS CLI for Lambda](http://docs.aws.amazon.com/cli/latest/reference/lambda/)
* [AWS Lambda blog](https://aws.amazon.com/blogs/compute/category/aws-lambda/)
* [Serverless](http://serverless.com/)
* [Claudia](https://github.com/claudiajs/claudia)
* [IOpipe](https://www.iopipe.com/)
## Thanks to
* [@sheffieldDevops](https://twitter.com/sheffieldDevops)
* Sky Betting and Gaming
* Presentation software [reveal.js](http://lab.hakim.se/reveal-js/#/)
* Diagram software [draw.io](https://www.draw.io)
We're hiring [@SkyBetCareers](https://twitter.com/SkyBetCareers), mention @brabster :)
## Thank you
For turning up and listening!
* I'm [@brabster](https://twitter.com/brabster)
* This presentation is on [GitHub Pages](https://brabster.github.io/talk-awslambda-intro)
Good luck with your Serverless adventures!