holy-lambda

steveb8n 2021-06-25T00:28:56.019600Z

@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?

Karol Wójcik 2021-06-27T07:11:56.053100Z

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

Karol Wójcik 2021-06-27T07:17:28.054200Z

@steveb8n

Karol Wójcik 2021-06-27T07:19:25.055900Z

At that moment I’m a little bit confused what’s stops you from using HL. Have you tried using it :D?

steveb8n 2021-06-27T07:26:32.056100Z

no I haven’t tried HL yet but I expect to do so this week.

steveb8n 2021-06-27T07:27:12.056300Z

I considered the low-level approach after hearing from you that HL isn’t really designed for CI and lambdas already in place

steveb8n 2021-06-27T07:27:38.056500Z

but it sounds like there is a way to do this

steveb8n 2021-06-27T07:28:47.056700Z

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

steveb8n 2021-06-27T07:29:11.056900Z

@karol.wojcik does that all make sense?

Karol Wójcik 2021-06-27T07:32:42.058900Z

Not at all

Karol Wójcik 2021-06-27T07:35:27.062800Z

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.

steveb8n 2021-06-27T07:36:27.063800Z

ok. in that case I don’t know enough yet to make sense. let me have some time to play with it and learn

steveb8n 2021-06-27T07:36:52.064500Z

then I’ll come back with questions later. that way I don’t waste your time

Karol Wójcik 2021-06-27T07:37:06.064900Z

In my opinion you will only get frustrated by this “low level” approach and sooner or later come back here where we started.

Karol Wójcik 2021-06-27T07:37:15.065400Z

I can have a call with you to showcase some stuff if that helps

Karol Wójcik 2021-06-27T07:37:35.066100Z

I’m always keen to help and make developers life easier

steveb8n 2021-06-27T07:38:06.066400Z

I’ll start with HL since it looks like the right level but I won’t know till I try it

steveb8n 2021-06-27T07:38:20.066600Z

thanks. me too 🙂

steveb8n 2021-06-27T07:38:29.066800Z

I’ll touch base when I need help

Karol Wójcik 2021-06-27T07:39:24.068Z

Btw AFAIK for this lambdas in place I think I have the best solution for you.

Karol Wójcik 2021-06-27T07:41:22.070400Z

You can deploy a new lambda, test it etc and then use it’s ARN in CDK ;>

steveb8n 2021-06-27T07:43:00.070600Z

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?

steveb8n 2021-06-27T07:44:50.070800Z

probably best for me to learn by trying it out 🙂 I’ll try to answer my own questions first

Karol Wójcik 2021-06-27T08:11:20.071Z

You can use whatever tool you want 😄 We go in circles 😄

Karol Wójcik 2021-06-27T08:12:47.071200Z

It took me 10 minutes 😄 https://github.com/FieryCod/holy-lambda/tree/master/examples/bb/native/cdk-example

Karol Wójcik 2021-06-27T08:13:00.071400Z

It's really easy once you know exactly what happens in HL

Karol Wójcik 2021-06-27T08:15:34.071600Z

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

Karol Wójcik 2021-06-27T08:15:50.071800Z

Does it make sense?

steveb8n 2021-06-27T08:21:08.072Z

yes! this is the first thing I will try. thanks

Karol Wójcik 2021-06-27T08:22:34.072200Z

You welcome. In the meantime I'm fixing CI support 🙂 I will add an example with azure-pipelines

Karol Wójcik 2021-06-27T17:06:33.072400Z

@steveb8n Here is the working example of HL + Azure Pipelines.

Karol Wójcik 2021-06-27T17:06:33.072600Z

https://github.com/FieryCod/holy-lambda-azure-cdk-deployment

Karol Wójcik 2021-06-28T06:14:41.073100Z

@steveb8n let me know if it helps

steveb8n 2021-06-25T00:29:49.019700Z

In other words, can the bb CLI be used to build/deploy a native runtime into an existing lambda?

steveb8n 2021-06-25T02:50:30.019900Z

now that I think about it, I only want to deploy a new lambda. don’t need gateway etc. Is that possible?

Karol Wójcik 2021-06-25T04:49:24.021800Z

Hmm.. I don’t know if it’s possibile to replace existing lambda.

Karol Wójcik 2021-06-25T04:50:10.023Z

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.

Karol Wójcik 2021-06-25T04:55:17.026700Z

@steveb8n

steveb8n 2021-06-25T06:14:56.026900Z

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

steveb8n 2021-06-25T06:15:18.027100Z

then CI deploys updates using a bb script

steveb8n 2021-06-25T06:15:41.027300Z

occasionally I manually upload a layer change

steveb8n 2021-06-25T06:16:30.027500Z

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

steveb8n 2021-06-25T06:17:03.027700Z

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

Karol Wójcik 2021-06-25T07:17:35.029800Z

@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

Karol Wójcik 2021-06-25T07:21:16.030100Z

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.

Karol Wójcik 2021-06-25T07:23:42.030300Z

I'm happy to help you out if you find any troubles with integrating CDK with HL.

steveb8n 2021-06-25T07:27:11.030600Z

great. I’ll note these steps and will refer back when I try it out. should be in the coming weeks

steveb8n 2021-06-25T07:27:19.030800Z

I’ll report back with findings

steveb8n 2021-06-25T07:28:22.031Z

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

Karol Wójcik 2021-06-25T07:28:41.031200Z

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.

Karol Wójcik 2021-06-25T07:29:10.031400Z

Do you use docker in your CI?

Karol Wójcik 2021-06-25T07:29:35.031600Z

I mean does your CI pipeline runs inside docker?

steveb8n 2021-06-25T07:30:15.031800Z

yes. Bitbucket pipelines uses docker images

steveb8n 2021-06-25T07:31:03.032Z

and you can use your own machines https://support.atlassian.com/bitbucket-cloud/docs/set-up-and-use-runners-for-linux/

steveb8n 2021-06-25T07:32:24.032300Z

same as github actions

Karol Wójcik 2021-06-25T07:36:23.032500Z

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

Karol Wójcik 2021-06-25T07:37:13.032800Z

To sum up. Integrating CDK with HL should be relatively easy. Integrating HL with CI not so much. 😄

Karol Wójcik 2021-06-25T08:30:29.033Z

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

steveb8n 2021-06-25T08:54:58.033300Z

Probably a four of steps too deep for me to say I understand 😃

steveb8n 2021-06-25T08:55:30.033500Z

But I will be learning all this soon

steveb8n 2021-06-25T08:56:58.033700Z

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

Karol Wójcik 2021-06-26T12:25:35.034500Z

I have some free time today, so I will bake up the tutorial for you ;)

steveb8n 2021-06-26T22:56:29.034700Z

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

steveb8n 2021-06-26T22:57:59.035Z

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

steveb8n 2021-06-28T07:18:48.073300Z

@karol.wojcik I will thanks. it shows me that I didn’t explain myself clearly enough though…

steveb8n 2021-06-28T07:19:23.073500Z

I use CDK manually, not via CI. This is because CDK/stack changes are high risk.

Karol Wójcik 2021-06-28T07:19:46.073700Z

What for do you use CI then?

steveb8n 2021-06-28T07:19:49.073900Z

instead, in CI I use BB scripts to update the lambda config and code using the AWS api

Karol Wójcik 2021-06-28T07:20:15.074100Z

lambda config and code?

steveb8n 2021-06-28T07:20:30.074300Z

I’ll paste in a snippet

steveb8n 2021-06-28T07:21:57.074500Z

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”

steveb8n 2021-06-28T07:22:11.074700Z

this is one of the commands from my CI script to update the code

steveb8n 2021-06-28T07:22:33.074900Z

I have others that update config but the code is the important part from an HL perspective

steveb8n 2021-06-28T07:22:54.075100Z

sorry that I didn’t make this clear yesterday

Karol Wójcik 2021-06-28T07:24:09.075300Z

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.

steveb8n 2021-06-28T07:24:33.075600Z

cool, that’s what I was hoping to do

Karol Wójcik 2021-06-28T07:24:43.075800Z

bb stack:executable produces a deployable zip file 🙂

steveb8n 2021-06-28T07:24:53.076Z

now maybe you grok why I kept mentioning ECR

Karol Wójcik 2021-06-28T07:25:03.076200Z

Actually not so much

Karol Wójcik 2021-06-28T07:25:10.076400Z

Why you need ECR there?

steveb8n 2021-06-28T07:26:09.076600Z

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

steveb8n 2021-06-28T07:26:42.076800Z

in your CDK example you demo that it’s possible to create a docker lambda without ECR. that is a CDK feature I think

Karol Wójcik 2021-06-28T07:26:52.077Z

Yes it is. But HL does not uses docker images for lambdas 😄

Karol Wójcik 2021-06-28T07:27:14.077200Z

Nope.. HL does not pack lambda in docker image never ever

steveb8n 2021-06-28T07:27:19.077400Z

oh. ok

Karol Wójcik 2021-06-28T07:27:22.077600Z

Always to zip

steveb8n 2021-06-28T07:27:37.077800Z

cool. even simpler

Karol Wójcik 2021-06-28T07:27:39.078Z

babashka, native = zip java = jar

steveb8n 2021-06-28T07:28:04.078200Z

that makes me happy. avoiding docker is a lot less complexity

Karol Wójcik 2021-06-28T07:29:14.078400Z

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 😄

steveb8n 2021-06-28T07:29:18.078600Z

so the zip contains a native handler that is invoked via some kind of custom runtime? i.e. it’s not nodejs, go, etc

Karol Wójcik 2021-06-28T07:29:44.078800Z

Zip user code + native runtime bundled together

steveb8n 2021-06-28T07:29:52.079100Z

I can probably RTFM this 😉

steveb8n 2021-06-28T07:30:18.079300Z

but great. I’m looking forward to it more now

steveb8n 2021-06-28T07:30:30.079500Z

gotta get one customer feature done and then I’ll be trying this out

steveb8n 2021-06-28T07:31:40.079700Z

I’ve been assuming the docker runtime all through this conversation. damn assumptions!

Karol Wójcik 2021-06-28T07:31:56.079900Z

😄

Karol Wójcik 2021-06-28T07:32:08.080100Z

native runtime is graalvm compiled clojure

Karol Wójcik 2021-06-28T07:32:40.080300Z

I'm using docker to make sure the artifact will work in the Lambda environment, and that's it 😄

steveb8n 2021-06-28T07:33:37.080500Z

sweet. in that case I’m all in

Karol Wójcik 2021-06-28T07:34:01.080700Z

https://github.com/FieryCod/holy-lambda/blob/master/src/fierycod/holy_lambda/native_runtime.clj#L94 Here is the native runtime impl

steveb8n 2021-06-28T07:34:06.081Z

I’m a fan of interceptors too so that’s a bonus. I presume I should tread lightly with interceptors for now

Karol Wójcik 2021-06-28T07:34:20.081200Z

Interceptors are very naive right now

Karol Wójcik 2021-06-28T07:34:36.081400Z

I would love to have the feature parity with pedestal, but it requires much work

Karol Wójcik 2021-06-28T07:35:00.081600Z

I cannot use any available library since most likely it's not compatible with babashka or nodejs.

steveb8n 2021-06-28T07:35:29.081800Z

ok. in my jvm stack I use the pedestal interceptors lib so I have all features

steveb8n 2021-06-28T07:35:45.082Z

I thought it might be due to graal compat

steveb8n 2021-06-28T07:35:52.082200Z

that’s good to know

Karol Wójcik 2021-06-28T07:36:35.082400Z

pedestal interceptors are not supported in HL. I mean if you want to embed pedestal interceptors to :interceptors it will not work

steveb8n 2021-06-28T07:37:07.082600Z

no probs. my lambdas are pretty simple so I can do without interceptors

steveb8n 2021-06-28T07:40:03.082800Z

ok I have what I need. I’ll let you know when I have something working

steveb8n 2021-06-28T07:40:09.083Z

thanks again

Karol Wójcik 2021-06-28T07:41:13.083200Z

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

steveb8n 2021-06-28T07:48:00.083400Z

you too mate

steveb8n 2021-06-28T07:48:22.083600Z

(it’s nighttime here in Sydney 🙂

Karol Wójcik 2021-06-28T07:50:25.083800Z

Huh, I'm just starting my work. 😄