@karol.wojcik this is a great project. thanks! I want to use it to generate a native lambda to replace an existing Lambda/API gateway setup. Is this possible? Or do I always get a full Holy stack using this project?
The technique described in article is pretty low level. Differences between HL and this approach are: • it’s hard to export multiple lambda functions, whereas in HL is very easy. • Input/output is not coerced to edn • Testing is hard, since you would have to mock input/output stream, whereas in HL you just do (u/call #’SomeFunction MockedRequestEdn) • You would have to think how to test the lambda before the you deploy it. In HL you can test lambda in Java via local api or invoke, so development iterations are faster. • HL automatically removes unnecessary reflect/resource native configuration to make your native artifact smaller • In HL at any time you can switch between Java/Native/Babashka runtime • HL unifies local/production payloads • HL properly packs your code = less GraalVM issues • HL supports very naive interceptors (subject to change) • HL support native configuration gen via native agent. You don’t have to make sure that all the branches of the code are covered by the agent. Just use agent/in-context. • In HL you can opt-out from using in-context and provide multiple payloads which are then used by the agent • HL understand some of the content-types and can automatically generate a proper response based on it • HL provides response utils for convenience • HL supports redirects, sqs event ack etc
At that moment I’m a little bit confused what’s stops you from using HL. Have you tried using it :D?
no I haven’t tried HL yet but I expect to do so this week.
I considered the low-level approach after hearing from you that HL isn’t really designed for CI and lambdas already in place
but it sounds like there is a way to do this
so maybe I just need to jump in with HL and figure out which steps I need to use to generate a docker image that I can upload to ECR. once I have it in ECR, it’s easy for me to update the lambda
@karol.wojcik does that all make sense?
Not at all
First of all HL can be used for as you said lambdas already in place. I gave you all the instructions to do it. Regarding CI it’s not so hard to adapt HL to be ran on this environment. I don’t know why you need ECR, docker image for the lambda.
ok. in that case I don’t know enough yet to make sense. let me have some time to play with it and learn
then I’ll come back with questions later. that way I don’t waste your time
In my opinion you will only get frustrated by this “low level” approach and sooner or later come back here where we started.
I can have a call with you to showcase some stuff if that helps
I’m always keen to help and make developers life easier
I’ll start with HL since it looks like the right level but I won’t know till I try it
thanks. me too 🙂
I’ll touch base when I need help
Btw AFAIK for this lambdas in place I think I have the best solution for you.
You can deploy a new lambda, test it etc and then use it’s ARN in CDK ;>
ah, that’s where we think different. I want to provision as much of my stack as possible using CDK i.e. I will already have the lambda created, ready for updates i.e. new container images. will this still fit the HL tooling?
probably best for me to learn by trying it out 🙂 I’ll try to answer my own questions first
You can use whatever tool you want 😄 We go in circles 😄
It took me 10 minutes 😄 https://github.com/FieryCod/holy-lambda/tree/master/examples/bb/native/cdk-example
It's really easy once you know exactly what happens in HL
What I mean by deploying new lambda is that you don't want to mess up your running code. Therefore you can deploy a new lambda which does exactly the same what your current one is doing and then reference the ARN in the old one of the new one
Does it make sense?
yes! this is the first thing I will try. thanks
You welcome. In the meantime I'm fixing CI support 🙂 I will add an example with azure-pipelines
@steveb8n Here is the working example of HL + Azure Pipelines.
https://github.com/FieryCod/holy-lambda-azure-cdk-deployment
@steveb8n let me know if it helps
In other words, can the bb CLI be used to build/deploy a native runtime into an existing lambda?
now that I think about it, I only want to deploy a new lambda. don’t need gateway etc. Is that possible?
Hmm.. I don’t know if it’s possibile to replace existing lambda.
How do you deploy your current one and how do you manage the stack. HL is deployment tool independent. You can generate artifact for native runtime and deploy it however you want.
yeah, I realised I don’t want to deploy over an existing one but I do want a new one. I provision my entire system using CDK, including the lambdas
then CI deploys updates using a bb script
occasionally I manually upload a layer change
I presume with HL I will need to create a new (docker based) lambda. then I want use HL (or something else) to update that
It’s fine if this is not the HL sweetspot. I can use something else but HL has such nice tooling that I want to explore it first
@steveb8n You don't have to. HL packages all user code with native-runtime all together in zip file when using bb native:executable.
Check this issue: https://github.com/FieryCod/holy-lambda/issues/57
To make HL work with CDK you have to:
1. Copy bb.edn to you project: https://github.com/FieryCod/holy-lambda/blob/master/modules/holy-lambda-template/resources/leiningen/new/holy_lambda/bb.edn
2. Use bb stack:sync && bb native:executable to generate native artifact.
3. Reference native artifact from .holy-lambda/build/latest.zip in you CDK stack.
4. Put the "provided" runtime in CDK Lambda property
5. As a handler name use full ns coordinate like: com.company.SomeLambdaHandler
You would probably have some troubles with using HL with CI, since GraalVM requires at least 6 GB of RAM and bb stack:sync , bb native:executable require Docker.
I'm happy to help you out if you find any troubles with integrating CDK with HL.
great. I’ll note these steps and will refer back when I try it out. should be in the coming weeks
I’ll report back with findings
for CI, I can use a local runtime i.e. CI drives a machine with lots of mem on my own LAN instead of using cloud. but thanks for the warning
Perfect. Please report back your findings in the issue #57. Probably we will need some changes on HL side to integrate it with CI workflow.
Do you use docker in your CI?
I mean does your CI pipeline runs inside docker?
yes. Bitbucket pipelines uses docker images
and you can use your own machines https://support.atlassian.com/bitbucket-cloud/docs/set-up-and-use-runners-for-linux/
same as github actions
Got it. You would have to expose docker network to bb. Alternatively you can build your own tasks which don't use docker, but you will still native-image and java from GraalVM CE docker image: https://github.com/FieryCod/holy-lambda/blob/master/docker/Dockerfile.ce
To sum up. Integrating CDK with HL should be relatively easy. Integrating HL with CI not so much. 😄
Hmm. I think I can bake a special CI mode in which no docker will be involved, when running bb tasks. Still though you would have to provide GraalVM CE in your CI image. Does it make sense? @steveb8n
Probably a four of steps too deep for me to say I understand 😃
But I will be learning all this soon
In the past I have been able to use docker based CI to create and publish docker images to ECR so I will try that again
I have some free time today, so I will bake up the tutorial for you ;)
Thanks. Before you put too much time into it, I found this excellent article https://nitor.com/en/articles/fast-cold-starts-for-clojure-in-aws-lambda-using-graalvm-native-image
I”ve been thinking I’ll try just using that technique but I don’t understand how it compares to using HL for the same thing on a project where I want CI to update lambdas already created. Interested in your thoughts @karol.wojcik
@karol.wojcik I will thanks. it shows me that I didn’t explain myself clearly enough though…
I use CDK manually, not via CI. This is because CDK/stack changes are high risk.
What for do you use CI then?
instead, in CI I use BB scripts to update the lambda config and code using the AWS api
lambda config and code?
I’ll paste in a snippet
aws “lambda” “update-function-code” --output “json” --region “ap-southeast-2" --zip-file “<fileb://cljs-out/api-v2-sqs-dispatcher/nextdoc.zip>” --function-name “nextdoc-sfdc-lb-regional-apps-sqs-dispatcher”
this is one of the commands from my CI script to update the code
I have others that update config but the code is the important part from an HL perspective
sorry that I didn’t make this clear yesterday
Ok got it. You can then build a lambda on CI (bb stack:compile && bb native:executable) then copy and upload a zip whenever you want, then reference it in update-function-code.
cool, that’s what I was hoping to do
bb stack:executable produces a deployable zip file 🙂
now maybe you grok why I kept mentioning ECR
Actually not so much
Why you need ECR there?
again, I might be misunderstanding but I presume that, for docker lambdas, the source of the handler is an image loaded from a docker registry i.e. ECR
in your CDK example you demo that it’s possible to create a docker lambda without ECR. that is a CDK feature I think
Yes it is. But HL does not uses docker images for lambdas 😄
Nope.. HL does not pack lambda in docker image never ever
oh. ok
Always to zip
cool. even simpler
babashka, native = zip java = jar
that makes me happy. avoiding docker is a lot less complexity
I did not want do over-complicate things. That's why I was so surprised when you started talking about ECR. It's complex and not fun stuff 😄
so the zip contains a native handler that is invoked via some kind of custom runtime? i.e. it’s not nodejs, go, etc
Zip user code + native runtime bundled together
I can probably RTFM this 😉
but great. I’m looking forward to it more now
gotta get one customer feature done and then I’ll be trying this out
I’ve been assuming the docker runtime all through this conversation. damn assumptions!
😄
native runtime is graalvm compiled clojure
I'm using docker to make sure the artifact will work in the Lambda environment, and that's it 😄
sweet. in that case I’m all in
https://github.com/FieryCod/holy-lambda/blob/master/src/fierycod/holy_lambda/native_runtime.clj#L94 Here is the native runtime impl
I’m a fan of interceptors too so that’s a bonus. I presume I should tread lightly with interceptors for now
Interceptors are very naive right now
I would love to have the feature parity with pedestal, but it requires much work
I cannot use any available library since most likely it's not compatible with babashka or nodejs.
ok. in my jvm stack I use the pedestal interceptors lib so I have all features
I thought it might be due to graal compat
that’s good to know
pedestal interceptors are not supported in HL. I mean if you want to embed pedestal interceptors to :interceptors it will not work
no probs. my lambdas are pretty simple so I can do without interceptors
ok I have what I need. I’ll let you know when I have something working
thanks again
No prob 😄 You will probably fail first time with native runtime and come back 😄 That's quite natural. GraalVM is not so trivial beast! 😄 Have a nice day
you too mate
(it’s nighttime here in Sydney 🙂
Huh, I'm just starting my work. 😄