PHP ON LAMBDA
WITH CUSTOM RUNTIMES
ConFoo Montreal 2020
Ian Littman /
@iansltx
Follow along at
https://ian.im/lambfoo20
Questions We'll Answer
Why you'd use Lambda, and what caveats come with using it
How Lambda works with Custom Runtimes (including PHP)
How to build an email reply bot with Lambda, SES, S3, and PHP
How to build a Lambda-powered API via API Gateway
Bonus: How to build API Gateway endpoints with
Bref
Topics We won't cover
A deep dive into Bref or Serverless Framework
Building Lambda applications via AWS's CLI
AWS SAM
Laravel Vapor
WHY LAMBDA?
No servers to manage
No worrying about concurrency within an app instance
Quick automatic scaling + h
igh levels of concurrency
Very granular billing + fair-sized free tier
Stateless per-request, shared-nothing-ish
Integrates with other AWS components
What kinds of integrations?
Trigger events from
S3
,
SNS
,
SQS
Application Load Balancer (billed for capacity + time)
API Gateway (billed per request)
Shared-nothing-ish?
AWS keeps Lambda containers around for a bit
to avoid "cold start" penalties
500 MB in /tmp is available per-instance;
can use as a cache
Instances != invocations
Instances == concurrency
A note on performance
CPU speed scales with RAM allotment
Minimum: 128 MB
Maximum: 3008 MB
Increment size: 64 MB
At 1792 MB you have one full core (stop there)
Using Serverless (e.g. via Bref)? Default is 1024 MB
There are a few other limits to keep in mind
Virtual Private Caveats
No internet connectivity by default
NAT Gateway
is $$$ (5¢/hr + 5¢/GB in Canadian region)
Workaround: split functionality between functions
Internet-connected, outside VPC (external APIs)
Internet-disconnected, inside VPC (internal resources)
Cold start times
No longer an issue as of late 2019
So, what about PHP on Lambda?
Custom runtime support has been available since 2018
Build the file system needed to run your function code
Store the file system as one or more (up to 5)
Layers
Worker-based, long-polling-esque model
NOT
HTTP request based without additional abstractions
Layers
Extracted to /opt (function code is in /var/task)
Versioned
Can include library dependencies (e.g. /vendor)
Zipped + submitted to AWS API (like functions)
Function specifies inclusion order
Custom runtime lifecycle
Bootstrap (cold start)
Task execution (warm start)
Lambda decides when to kill the instance
Inactivity timeout (~10 minutes)
Task deadline (configurable, up to 15 minutes)
Bootstrap (Cold start) phase
Initialize runtime
Prep function for execution
Pass env vars including file/method for handler function
If there's an error init-ing,
make an API call
Task execution (warm start) Phase
Call APIs to process work
Next invocation
(GET)
Request ID and more in headers
Task data in response body, JSON-encoded
Invocation response
(POST)
Request ID in URL
Response in body
Consuming services may require specific format
Logging & Errors
Invocation error
(POST)
STDOUT -> CloudWatch Logs
Metrics available via CloudWatch (or in function UI)
What might this look like from AWS's Side?
Are any workers for target function waiting on work?
If so, skip to step 3; if not...
Build a new instance (layers + function code)
Run /opt/bootstrap (or /var/task/bootstrap)
Wait for it to do one of the following
Return nonzero from the bootstrap (init failure)
Call the init error API endpoint
Call the task request API endpoint
Respond to the next invocation endpoint with event
Wait for API calls to invocation success/failure or timeout,
whichever comes first
Example 1: email spongebot
SES rule pushes email to S3
S3 triggers Lambda
Lambda function executes...
Grabs email from S3
Parses using MIME parser
RaNdOMlY CaPiTaLiZeS LEtTerS
Sends email reply via SES
Example 2: Spongebot API
HTTP request hits API Gateway
Lambda function executes...
Grabs query string parameter if there is one
RaNdOMlY CaPiTaLiZeS LEtTerS
Sends a JSON response
API Gateway turns the Lambda payload into an HTTP response
...but you should probably use
Bref
in prod
...or
Vapor
for Laravel-ites
returntrue.win
uses Bref
Bonus: Example 2 (API Gateway) via Bref
Further Reading
An early post on PHP-on-Lambda by Michael Moussa
Bref docs
Firecracker
(underlying "microVM" layer for Lambda)
Thanks! Questions?
https://ian.im/lambfoo20
- this presentation
https://github.com/iansltx/spongebot
- sample code
https://twitter.com/iansltx
- me
https://github.com/iansltx
- my code