The Case of the Broken Lambda
veekaybee.github.io
veekaybee.github.io
Actually, we just open-sourced a template for using Lambda with Chalice and Terraform that automates this and many other relevant steps: https://github.com/chanzuckerberg/chalice-app-template. It's not 100% directly applicable to this use case yet, because SAM/CloudFormation templates don't have a good way to manage bucket event subscriptions. But domovoi (https://github.com/kislyuk/domovoi) can manage S3 event subscriptions (direct or bridged through SNS, SQS, or SNS-SQS) in an idempotent declarative (non-IaC) process.
And they were close to a solution. They have a CI pipeline which can and should be doing the packaging for them. The Linux image only has to be close enough to Amazon Linux, not exactly Amazon Linux. Heck, even CodeBuild uses Ubuntu [0].
It also doesn't help that there's a lack of information or simply misinformation out there. Sometimes I think frameworks with a very specific use-case like Zappa do more harm than good. Yes, it's easier to get running, but it doesn't give you a general purpose solution and makes you think everyone is just hacking around the mess.
Serverless' serverless-python-requirements is a good solution if you can't be bothered having the CI do the packaging/artifact creation.
[0] https://docs.aws.amazon.com/codebuild/latest/userguide/build...
It's not like there is a lot of "vendor lock in" for a 10 line yml file.
I'm generally unwilling to learn skills that only apply to a proprietary environment. If aws was using openwhisk, I'd probably code directly against that instead of using a hack like zappa.
With CodeBuild you would just specify the bash commands you want to run to create your zip file with a yml file.
But you’re already talking about using lambda so you’re already using something proprietary.
On a deeper level, if you work for a company, you’re probably learning a lot of business specific stuff anyway that’s not transferable.
As part of the buildspec.yml just import all of your dependencies using
pip install {package} -t . # (The period at the end forces it to install in the local directory.
In your artifacts section make sure you include everything.
CodeBuild will then create a zip file that you can load into the console.
For bonus points, once you create the lambda manually for the first time using the AWS console, you can export the CloudFormation yml file and use that as part of your automation strategy where you have a CF Parameter that specifies the name of your zip file that was uploaded to S3 by CodeBuild.
I use this strategy all of the time to develop on Windows and deploy to lambda.
Cross platform Python is tough, especially when you use dynamically linked C libs on a platform that can change versions without warning.
Run `docker run --name lambdapy36 -it -v $(shell pwd):/mycode lambci/lambda:build-python3.6 /bin/sh -c "pip install -r /mycode/requirements.txt -t /mycode/vendored/"`
All your packages are now compiled for the lambda env and have been placed in the /mycode/vendored folder. Either move them into the root before deploy or add /var/task/vendored to Lambda's python path by setting PYTHONPATH: "/var/runtime:/var/task/vendored"
You can usually count on having native libraries for a given activity for Java, so you can just use a JVM-based language (does Lambda support that? I bet it does.)
The POM packaging and jar based deployment seemed to make the dependencies work.