Into The Box 2019 Notes: Serverless CFML on AWS Lambda, Pete Freitag

May 08, 2019

Lambda - function that runs in AWS

needs something to “trigger” to make the function run

What triggers does Lambda support?
http request - api gateway, app load balancer
s3 event - when a file is uploaded to a bucket
SNS
SQS - queue message. “when an order comes into my app”, etc.
AWS will auto-involve the Lambda to process the msg for you.

if using Aurora or Dynamo DB, can also set up db triggers
any time a row is updated in the db, can figure a lambda function to do something else.

whole key - it’s not just for an HTTP request coming in
think about events that happen that can trigger these lambda functions
which can trigger /another/ event to happen and so on
can build really cool architectures that way

You can use Fuseless to do this all with CFML!

myth busters -

the ZIP file will be huge
- actually around 20mb and will get smaller over time
- Lucee 6 is going to be more streamlined and smaller

Node apps will be smaller than Lucee
- the node-modules folder can get huge easily. 100mb+ often
- these are not always tiny
typically have to install a bunch of modules
- lucee has a lot of that built into core apis

Java must be the slowest way to run this
- actually runs very fast once it’s warmed up
one of the most consistent performance times, once it’s warmed up
there are ways to deal with cold starts to speed that up too.

What is serverless? —
it means the server OS is abstracted away, you don’t have to care about it
need to know that it’s Linux based, but that’s about it
- needed for how file paths will be structured

takes the OS work off your plate as far as maintenance is concerned

stateless -
sever might only live for 10 minutes
have to manage state in other ways beyond “server memory”

minimal config dials (two)
RAM
Max Concurrency

but there are limitations
need to know them, what to expect when putting it into producction

Benefits of Serverless -
zero spinup
lamda builds end up being very small
only bulled when your code is processing something
don’t spend money for idle time

compared to EC2 clustering setup
have periods of times when it goes up to lots of servers for lots of requests
but that burst of requests scales up/down much quicker than EC2 servers

Zero OS patching

runs in a “least privledged” execution model
you create an IAM role, permission for what it needs
you /could/ give it “everything permission” and bypass the “least privilege” benefit
“this lambda function can only access THIS specific s3 bucket” for example
creates a really good security model

billing for this are “milliseconds” increments

AWS lambda security -
lots of this gets pushed out to AWS to worry about

Limitations of Lambda -
15 min MAX execution time
- a single exec request can only last for 15 minutes

don’t know how long your server instance will actually last for
can be 1 minute, 1 hour, etc.
max ram you can allocate is 3008MB - more than enough for most case

Cold Starts -
one of the downsides
1st request coming into to Lambda, has to do a few steps
download the Zip into the lambda execution env
runs a “startup” method
in the case of Fuseless, starts up the Lucee engine, takes a little time
Performance hit of 0.8 - 2 seconds (or higher within a VPC)
cold starts happen if a req comes in and there is no available container to execute the lambda function
if you get a simultaneous request, it will start up a 2nd instance, and it will scale up among multiple containers
this is where the “serverless vs containers” debate comes form
containers can run long running processes, can keep running for longer periods of time, so fewer “cold starts”

Dealing With Cold Starts -
Reduce the size of your ode ZIP
- your code must be downloaded from S3
- ZIP file extracted
it’s doing a lot of work here
Can also increase the amount of RAM, that reduces the cold start duration
(at a minimum usually go with 1024)
increasing the “ram dial” will also crease CPU speed in the same step

can also pre-compile CFML into Java Byte code
the more .cfm .cfc,s the more compilation time on first request
if you have just a single CFC file as your function this probably wont make much difference.

* hit concurrently to ensure multiple instances are awake
have a “function warmer” - scheduled task which makes requests every few minutes to keep the function warm so that when requess come in it has available containers to process
you’re only paying for the request times coming in

Lambda Pricing -
.20 per 1M requests
- first 1M free each month!

get about 800K requests at 1GB RAM running for 500ms is free
Calculator: serverlesscalc.com

API Gateway -
for serving HTTP requests
pretty good free tier here too.

Corey Quinn - “last week in AWS NEWS letter”

Some Required Tools for Fuseless -
Gradle - Java Build Tool
- let’s you download JAR files pretty easily (eventually this will become a CommandBox command)
AWS SAM CLI - aws.amazon.com/serverless/sam/
Download github.com/foundeo/fuselsss-template
or go to fueselsss.org
and click download template
run “init.sh”
-downloads lucee.jar and fuseless.jar

What Version of Lucee?
if downloading this manually, you want Lucee 5.3+ Light
smaller than the full version
light ver doesn’t have any extensions installed by default

Fuseless Folder Structure -
/cfml/app - your code goes here. all you /need/ is an app.cfc. put something on onRequest(). that’s your lambda function
/jars - requires a lucee.jar and fuseless.jar. plus any jars you want your lambda function to be able to use
/build.gradle - the “Apache ANT” style build file, or box.json, etc.
/template.yml - useful if you want to test locally. or for setting up a CI deployment pipeline. if you just want to create a ZIP and upload it to Lambda you don’t need this part.

then run “gradle build”
it packages everything into a ZIP file under the /build/distribution
that’s the entire fuseless-tempalte.zip

Run it Locally -
gradle build
- packages your lambda function into a zip file
“sam local start-api”
for testing locally
SAM is AWS command
“serverless application model”
takes the template, reads that, sets up a local version to test
http localhost:3000/dump.cfm

TESTING
local testing API is slow
use CommandBox for local dev then test builds
- there are differences and limitations in Lambda that make it important to test it in both places
occasionally something works in 1 and not the other
important to test on AWS infrastructure

Okay Let’s Deploy!
Upload Zip file to AWS console or S3
- generally discoursed, old school approach. probably best way for just playing around to make sure it works, but not an approach for going into production.
For production, consider the “SAM template”
- generates a Cloud Formation template, can deploy in cloud formation

“CodeStar”
you start a project, it sets up all the Lambda stuff for you
every time you commit code, it auto deploys to Lambda for you

in AWS console
“create function
give it a name
select runtime Java 8
set permissions - IAM security model
if your’e new use “create a new role w/ basic Lambda permission” - all it can do is execute the function, nothing else. can add other permissions later to talk to s3 buckets, etc.
“create function”

(demo time)

Other Lambda Limits -
file system is read-only except for/tmp/ - 512 mb max
FuseLess uses part of /temp -
(tip: use ram://)

Code Size Limit: 250mb uncompressed
No Lucee Admin, everything must be configured via app.cfc environment variables

AWS API Gateway Limitation -
max 29 second request
not designed for long running requests

Fuseless In Action -
Fixinator runs on AWS Lambda with Fuseless

Down the Road -
Fuseless CommandBox command is coming, to replace the Gradle build steps
easier template init’ing
perform CFML spec build optimizations
inject Lucee extensions

Fuseless CFML API
- abstract common code
- helper methods, standard way of working w/ it to get access to things like the logger, etc.

foundeo.com