Build Go Apps That Scale on AWS

Bundling the Lambda



Build Go Apps That Scale on AWS

Check out a free preview of the full Build Go Apps That Scale on AWS course

The "Bundling the Lambda" Lesson is part of the full, Build Go Apps That Scale on AWS course featured in this preview video. Here's what you'd learn in this lesson:

Melkey uses the awslambda package in the CDK to build out the lambda function. The runtime, code payload, and the handler function to invoke are specified.


Transcript from the "Bundling the Lambda" Lesson

>> And now, this is where, like I said everything the source of truth to everything in this main function, right? And you may think we need to pass in handle request, and then event like so. That's not the way we're gonna deploy a lambda. We're gonna do is lambda which can bring in that package from up.

I was gonna say upstairs, we're gonna bring it in. So, let's keep our format. And in here,, okay? If we go back down, this lambda is gonna take an argument. Or we're gonna call a method on this, which is start. And then we pass in our function here, our handle request.

And you may have noticed, there is no call, we're not calling handler request. We're not doing this. And the reason for that is functions are first class citizens in Go. Meaning, you can pass functions as values as well. Okay, so essentially, we're not telling, lambda.start to call this function right away.

We're just saying, hey, lambda.start on invocation, okay? Here's the function that you're going to run, which are handle request function. And there's a lot of like really interesting complexity that goes behind the scenes of this. Cuz like I said, we created this type, we created as MyEvent. The go AWS SDK doesn't know what this is.

It doesn't know that has a user name, we could change that, right? So there's lots of interesting thought philosophy with using Go and how you can handle these cases of this unknown. We're gonna go to a few examples of these, but just recognize that lambda.start is not calling the function.

It's being passed a function to call. Cool, so, we're done with this main.go, we're done with our first definition of lambda. Let's switch gears back to our Go CDK file here for a second. So in this file, we're not going to touch anything that main.go. Actually, never going to touch this.

Just ignore it. We're going to touch everything, and this is our playground, okay? And here, as you can see the example resource define a new queue, we can define a new lambda. So, the first thing I want to do is this is why I guess I did remove the example.

That's okay. We're going to first bring in our example here. So let's see. The definition for that example, it's just And it's going to be V2 AWS Lambda. Cool, let's see that I get the right AWS-CDK. Let's go, before the V2. Sorry, it's a long, I think AWS CDK.

There you go. And you can see there's a different input right here. Already, now we're just going to complain that's unused. Before we're getting a different error message saying, hey, I don't know what this is. This is not importing our go.mod. I don't know what this is. Now, since we know return a compiler, hey, we have this and said yes, we do, now it's unused, okay?

So, here we're gonna keep the same structure as this resource, but let's clean up our car loop. Let's remove this line. Let's remove this line. And let's actually just remove everything for right now, okay? I'm going to use that same definition. So I'm going to do AWS Lambda.

I'm going to put New function, okay? And this new function takes certain properties. Just like anything else, we saw with the queue, we're going to see a DynamoDB. We're going to go to API Gateway. It takes specific properties to call this function. If you go dive into this new function, right?

You can see there's gonna be a few examples of how we can run it and what expects but here the first thing that we need to pass in Is our stack. That first baby piece that we kind of lay going onto is the stack. So now we're saying, hey, this stack is gonna have this lambda function, and we're gonna say the name of the function.

You can even see here new function expects a contract type, an ID, string and a props, which is AWS Lambda function props. So here let's I should give it an ID, js, double A string. And let's just call this MyLambda function. You can call whatever you want. This is just the ID of this particular lambda function.

And then we're gonna pass it a ref to AWS Lambda function props. I'm gonna open that up. And this is actually what I intended to go into first. So if we go in here, this is a very good resource to know and understand what does this really expect?

What can we call our function props? And there's some examples in the raw CDK code that shows you how to use this, and there's a really good example. The function prompts has these three properties, runtime, handler and code. Again, every resource is gonna have their own definition for properties.

These are lambda specific properties that we're dealing with here, okay? The runtime basically tells a lambda function hey, this is the runtime of a Code. This is what we've written our back end in. And again, this could be Python, this could be Node, Go, whatever. So it's important that we pass in our runtime.

The handler is basically where does this code exist, right? We're gonna bundle our code up, and then we have to use that code, give it to our lambda contract to be deployed with, okay? Because as of right now, if we do not give it a handler, we're gonna deploy quite literally an empty lambda.

So this handler is where our code should be packaged and bundled. And then the code, how do we actually execute our code, okay? Where is the code going to be executed and how are we going to get executed, right? So I can go back and show a quick example here.

So we can first pass in the Runtime, okay? And the runtime, unfortunately, GoCDK recently made a change in their runtime where, for Go, it used to support Go natively, but now we have to pass it in a custom runtime provision. So it's going to be Runtime_PROVIDED_AL2023, okay? And this is a recent change they've made.

They've deprecated support for bundling native Go functions, so we have to provide the runtime. But this actually isn't a big deal cuz, I'm gonna show you how Go makes it super easy for us to define the runtime of where you can run this code, okay? Next, is gonna be the code property.

So we're gonna say code. And in here, it's going to be AWS Lambda, and it's a few options. You can see it from Asset Image, and from Bucket. So you can actually host your application in sdbucket and reference it from there. You can host it on like a docker image or an ECR image, host it from there, or you can actually do from asset.

And from asset means we're gonna give you literally the function to run. So it's gonna be AWS Lambda. Oops, hold on. Asset code from Asset. And this, we have to pass in basically the path over this code is gonna live. So we're gonna do JSI string, because it needs to compile that string for us, right?

This JSI framework basically compiling a Goshen type to a TypeScript string type. That's kinda what it's doing under the hood, okay? And then the path. So this is gonna be lambda, the directory that we just created, and into what we're gonna call, okay? And then the nil is gonna be saying, we don't want to pass any additional properties.

There's nothing more that we wanna provide our asset from code. But it's gonna be straight zip, it's gonna have everything you need. You can deploy it, you can use it. There might be some further instances of, again, controlling granularity might be interested in, but no, for right now we don't need it.

And then the handler. And this is a very important kind of concept I wanna tie really back from when we first started writing code in the first part. Remember when I said, anytime you run code and Go the source of choose the main function and it has to be packaged main.

This is why, because when we run our Go code, you can actually compile it to machine code. They can execute anytime you want, but to do that successfully and to do that in a very intelligent way, you have to identify a specific package main. And that package main is expected to have a function called main, which serves as the entry point for our Go application.

I'm gonna show you a little example here. So we're gonna kind of deviate from this. If you go here, go to Go back to our lambda main.go. Yes, question.
>> Question about that before we get into that, the runtime, what's the relationship between the runtime and the code?

So if you have like a Ruby runtime-
>> Yeah.
>> Does that mean that you could run Ruby code without shipping Ruby? Like it's available in the Runtime already.
>> Yeah, specifically in Ruby and lambda, I don't know if that's supported, but conceptually, yes. So, let's say something I can probably speak further on as a node.

You're basically saying if the runtime is node, the lambda you're gonna deploy to is gonna have everything ready to run that version of node. And it's different but node 18, node 16 16 as one of the options there if I'm not mistaken. So it's basically telling, hey, this lambda function can call a typescript function that's going to run on node.

And in this case, we're gonna provide it the runtime. But let's say we did this like a year ago, it's gonna have to go runtime. The lambda is going to say, hey, we're gonna call this lambda function, it's going to run Go code on the Lambda, right? So you can't really mix up with Node and Go.

You're gonna have like a gnarly error. So you want to avoid that. But that's conceptually what it is. Because we're not gonna different from server-based architecture, we have to download like Node, all these dependencies to run your program. This is how we handle that in a serverless-based architecture.

That was a really good question, thank you. So I wanna showcase an ability of Go. Here we have this lambda.start, right? Do me favorite comment this out. And then all I want you to do is our classic format, print line, hello world, okay? We took a few steps back.

We've regressed, all right? Now in our Lambda directory, I want you to run it go run main dog, all right? That's how we do it. Hello World, cool. We've done this before, why am I showing you this? Here's some magic gobuild-outputmain. Did anyone see what happened? Something's different.

There's an acronym and see what it is.
>> Executable.
>> Yes, exactly. We have an executable main here. This compiled our entire Go code into machine code, right? And now you can just do main. You can execute as if it's scripted. As if it's just an executable piece of software, right?

And so now you can understand the power of how easy it is to deploy Go in different environments. CICD pipelines, all you gotta do is execute like this, right? And that's why we followed that package main main function entry point hierarchy. Because the source of truth of what this is going to run basically bubbles down to the main function.

Cool, all right, yes.
>> Can you bypass the whole runtime process and just upload that binary file to Lambda and execute it. That's like a Linux binary?
>> No, you can't, because, we're kind of going to do that in the next command, but we still have to tell the Lambda what the runtime is.

So even if we just give it this binary file, I think the way lambdas are constructed engineered, there's maybe too much wiggle room of what can happen on these deployment. So I think the team at AWS wanted to really confine what the runtime will be when you deploy it.

And again, you can think of like if you're deploying like Python runtime or something like that, you have to provide this runtime so it can do whatever it has to do to download everything to run your code successfully. And there's a reason why they remove the runtime. And we're gonna show why that is Is in just a second with like native go features.

Okay, so now we have this main. Let's go ahead and delete this. I was just showing you that for example. Fun fact, if you have go PLS on VS code or near him and you save something, it actually automatically brings in a package. So I didn't bring it in.

It kind of brought it in itself once I saved it.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now