bene@theodo.co.uk
Ben Ellerby
@EllerbyBen
@EllerbyBen
serverless-transformation
@EllerbyBen
@EllerbyBen
@EllerbyBen
💰 Cost reduction
👷♂️ #NoOps
💻 Developers focus on delivering business value
📈 More scalable
🌳 Greener
@EllerbyBen
Lambda
S3
Dynamo
API Gateway
Compute
Storage
Data
API Proxy
Cognito
Auth
SQS
Queue
EventBridge
Event Bus
@EllerbyBen
@EllerbyBen
@EllerbyBen
@EllerbyBen
@EllerbyBen
<?php
echo "Not my choice!";
?/>
@EllerbyBen
404
RUNTIME NOT FOUND
@EllerbyBen
200
Custom Runtimes
@EllerbyBen
HTTP API for custom runtimes to receive invocation events from Lambda and send response data back within the Lambda execution environment.
@EllerbyBen
curl
"http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next"
Next Invocation
Invocation Response
Invocation Error
Initialization Error
@EllerbyBen
Body: JSON Payload
Headers: Meta Data
https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html
GET
@EllerbyBen
Body: Response
https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html
POST
@EllerbyBen
Body: Error Object
https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html
POST
@EllerbyBen
A runtime is a program that runs a Lambda function's handler method when the function is invoked.
https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html
@EllerbyBen
bootstrap
Shell Script
Script in supported language
Binary file compiled on Amazon Linux
@EllerbyBen
bootstrap
Setup
Reading Handler Name (env)
Polling for invocations from API
Calling Handler with body
Posting response
@EllerbyBen
#!/bin/sh
cd $LAMBDA_TASK_ROOT
./node-v11.1.0-linux-x64/bin/node
runtime.js
https://docs.aws.amazon.com/lambda/latest/dg/runtimes-walkthrough.html
@EllerbyBen
#!/bin/sh
set -euo pipefail
# Initialization - load function handler
source $LAMBDA_TASK_ROOT/"$(echo $_HANDLER | cut -d. -f1).sh"
# Processing
while true
do
HEADERS="$(mktemp)"
# Get an event
EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next")
REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2)
# Execute the handler function from the script
RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA")
# Send the response
curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE"
done
https://docs.aws.amazon.com/lambda/latest/dg/runtimes-walkthrough.html
@EllerbyBen
runtime-tutorial
├ bootstrap
└ function.sh
https://docs.aws.amazon.com/lambda/latest/dg/runtimes-walkthrough.html
@EllerbyBen
bootstrap
handler
@EllerbyBen
bootstrap
handler
34M
@EllerbyBen
@EllerbyBen
@EllerbyBen
A layer is a ZIP archive that contains libraries, a custom runtime, or other dependencies. With layers, you can use libraries in your function without needing to include them in your deployment package.
https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html
@EllerbyBen
bootstrap
handler
handler
handler
@EllerbyBen
Reduce deployment package size.
Large dependency deployed less often.
Easier to manage when change rarely
Reduced code storage (75GB)
@EllerbyBen
https://aws.amazon.com/blogs/aws/new-for-aws-lambda-use-any-programming-language-and-share-common-components/
@EllerbyBen
layers:
php7:
path: layers/runtime
functions:
setup:
handler: hello
layers:
- { Ref: php7 }
@EllerbyBen
@EllerbyBen
#!/opt/bin/php
<?php
// amzn-ami-hvm-2017.03.1.20170812-x86_64-gp2
function getNextRequest()
{
$client = new \GuzzleHttp\Client();
$response = $client->get('http://' . $_ENV['AWS_LAMBDA_RUNTIME_API'] . '/2018-06-01/runtime/invocation/next');
return [
'invocationId' => $response->getHeader('Lambda-Runtime-Aws-Request-Id')[0],
'payload' => json_decode((string) $response->getBody(), true)
];
}
function sendResponse($invocationId, $response)
{
$client = new \GuzzleHttp\Client();
$client->post(
'http://' . $_ENV['AWS_LAMBDA_RUNTIME_API'] . '/2018-06-01/runtime/invocation/' . $invocationId . '/response',
['body' => $response]
);
}
// This is the request processing loop. Barring unrecoverable failure, this loop runs until the environment shuts down.
do {
// Ask the runtime API for a request to handle.
$request = getNextRequest();
// Obtain the function name from the _HANDLER environment variable and ensure the function's code is available.
$handlerFunction = array_slice(explode('.', $_ENV['_HANDLER']), -1)[0];
require_once $_ENV['LAMBDA_TASK_ROOT'] . '/src/' . $handlerFunction . '.php';
// Execute the desired function and obtain the response.
$response = $handlerFunction($request['payload']);
// Submit the response back to the runtime API.
sendResponse($request['invocationId'], $response);
} while (true);
?>
@EllerbyBen
@EllerbyBen
bootstrap
handler
local bootstrap
web
server
@EllerbyBen
@EllerbyBen
@EllerbyBen
https://bref.sh/docs/
@EllerbyBen
@EllerbyBen
The custom runtime API let's you run any binary you want.
Lambda layers are a great way to share large dependencies, like your runtime and bootstrap.
Lambda layers reduce your deployment size.
@EllerbyBen
AWS Lambda is a very flexible tool, use it wisely.
serverless-transformation
@EllerbyBen
@EllerbyBen