-
Notifications
You must be signed in to change notification settings - Fork 4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(lambda-go): higher level construct for golang lambdas #11842
Conversation
It looks like the tests are failing due to docker rate limit errors trying to pull the |
@eladb finally got all the tests passing. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
Don't know go
enough to correctly review this but sharing my experience from @aws-cdk/aws-lambda-nodejs
.
Wonder if the common logic/structure of @aws-cdk/aws-lambda-nodejs
and @aws-cdk/aws-lambda-golang
should be centralized somewhere...
...cdk/aws-lambda-golang/test/lambda-handler-vendor/vendor/github.com/aws/aws-lambda-go/LICENSE
Outdated
Show resolved
Hide resolved
I tried to follow the |
@jogold any additional feedback? |
@eladb let me know what the next steps are for this PR. Thanks! |
@eladb how can we help get this through? |
@corymhall Still on my radar. Apologies again for taking so long. Stay tuned. |
introducing a higher level construct to define golang lambda functions. This was inspired by the other high level constructs for Nodejs and Python Co-authored-by: gjohnson <[email protected]>
@jogold I think I need a little help with the integration tests. The asset hash that is generated is constantly changing so the tests keep failing. I've tried keeping everything as controlled as possible, even using AssetHashType.CUSTOM, but the hash that is generated in the PR build is always different, even when I manually update the |
The problem is here I think: with the aws-cdk/packages/@aws-cdk/core/lib/asset-staging.ts Lines 491 to 494 in b3c288d
There's the same problem in Still there's something to do to avoid those unstable hashes. |
return Code.fromAsset(path.dirname(options.modFilePath), { | ||
assetHashType: options.assetHashType ?? cdk.AssetHashType.OUTPUT, | ||
assetHash: options.assetHash, | ||
bundling: new Bundling(options), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Related to #11842 (comment)
Maybe the solution is to delete props
before passing this to bundling
.
Or explicitly only pass the public
properties...
Edit: I don't have the problem because I'm always using |
Co-authored-by: Jonathan Goldwasser <[email protected]>
Now you can switch to your default again for |
@jogold thanks for the help! It looks like the I'm hoping that by using an immutable tag |
mmm... it should have worked without your latest change. When using aws-cdk/packages/@aws-cdk/core/lib/bundling.ts Lines 273 to 279 in 96d4071
I would say that the hashes committed in If I go back before your latest change and run the integ test locally I don't get the same hash as you (i get Anyway it's fixed now and should not happen anymore. |
I was meaning that the docker image that I had cached locally for |
But your default is to use |
Good catch! Looks like I forgot to update the property documentation to match the behavior.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@corymhall finally I've picked this up. Apologies it took ages. This is an initial round of feedback, mostly focused on the README. Let's get this merged!
With this information the construct can determine what commands to run. You will | ||
generally fall into two scenarios: | ||
|
||
1. You are using vendoring (indicated by the presence of a `vendor` folder) | ||
In this case `go build` will be run with `-mod=vendor` set | ||
2. You are not using vendoring (indicated by the absence of a `vendor` folder) | ||
If you are not vendoring then `go build` will be run without `-mod=vendor` | ||
since the default behavior is to download dependencies |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not 100% clear how bundling result is different between the two modes? I think in both modes the eventual bundle needs to vend all dependencies, no? Wouldn't it simplify if we always require vending?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you are not vendoring your dependencies in a vendor
directory in the project, then Go will download dependencies into the module cache. If you have a vendor
directory then Go will use the dependencies there and not make any network calls. If you are using -mod=readonly
or -mod=mod
then Go will use the module cache or make network calls to download/update dependencies in the module cache. go build docs.
Some people prefer to vendor their dependencies and check it in to source control, while others prefer to have Go download the dependencies into the module cache during build.
|
||
## Docker | ||
|
||
To force bundling in a docker container, set the `forceDockerBundling` prop to `true`. This |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few words what does "bundling in a docker container" means and in what cases you might want to use it
|
||
This library provides constructs for Golang Lambda functions. | ||
|
||
To use this module you will need to have Docker installed. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to offer a local bundling experience that does not require docker to be installed? (similar to how NodejsFunction
allows you to install esbuild
locally)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, this comment should be removed since it does support local bundling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated!
Define a `GolangFunction`: | ||
|
||
```ts | ||
new lambda.GolangFunction(this, 'handler', { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this be GolangFunction
or just GoFunction
(same question for the module name nodejs-go
).
@MrArnoldPalmer @RomainMuller curious what you'll think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this better too, I'll update.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated!
}); | ||
``` | ||
|
||
By default, if a folder path is provided as the `entry`, the construct will assume there is a go entry file (i.e. `main.go`). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
By default, if a folder path is provided as the `entry`, the construct will assume there is a go entry file (i.e. `main.go`). | |
By default, if `entry` point to a directory, the construct will assume there is a Go entry file called `main.go`. |
What happens if entry
is a file?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It works both ways (file or directory). I've updated the property docs to explain what happens either way.
@@ -0,0 +1,12 @@ | |||
# The correct AWS SAM build image based on the runtime of the function will be | |||
# passed as build arg. The default allows to do `docker build .` when testing. | |||
ARG IMAGE=lambci/lambda:build-go1.x |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's use the official images from the public ECR repo - e.g. https://gallery.ecr.aws/sam/build-provided
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm using the image specified in the lambda.Runtime.GO_1_X.bundlingDockerImage
aws-cdk/packages/@aws-cdk/aws-lambda/lib/runtime.ts
Lines 161 to 163 in b4956ea
public static readonly GO_1_X = new Runtime('go1.x', RuntimeFamily.GO, { | |
bundlingDockerImage: 'lambci/lambda:build-go1.x', | |
}); |
The SAM team has not created bundling docker images for Go yet, and based on the docs doesn't actually support building Go functions in a container (only local build supported). The only Go image on the public ECR is the bitnami golang image. I'm using this in the integration test so I could update it to this, but then we should probably update the lambda.Runtime.GO_1_X.bundlingDockerImage
as well.
/** | ||
* Path to go.mod file | ||
*/ | ||
readonly modFilePath: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
readonly modFilePath: string; | |
readonly moduleDir: string; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also updated with some additional logic that verifies that you are providing a directory, and if you are providing a file, then it validates that it is a go.mod
file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Impressive work. Thanks for this awesome contribution! 🎉
@corymhall I expect this to take some time to mature. Would it be okay if we assigned any issues related to this module to you?
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
AWS CodeBuild CI Report
Powered by github-codebuild-logs, available on the AWS Serverless Application Repository |
Thank you for contributing! Your pull request will be updated from master and then merged automatically (do not update manually, and be sure to allow changes to be pushed to your fork). |
@eladb yeah definitely! |
introducing a higher level construct to define golang lambda functions. This was inspired by the other high level constructs for Nodejs and Python I'm setting a couple of things by default. *Environment Variables* * `GOOS=linux` * `GOARCH=amd64` * `GO111MODULE=on` *AssetHashType* * `AssetHashType.OUTPUT` I've added some details in the README on when you could change this to `INPUT`. I'm not really sure what the majority use case would be though. *Go Modules* I am requiring the use of Go modules which were added in Go 1.11 (current version is Go 1.15). I think at this point most Go developers will probably be using Go modules (for a comparison the [aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) requires 1.15) *Runtime* * `Runtime.PROVIDED_AL2` The `GO_1_X` runtime doesn't support newer Lambda features like Lambda extensions, and the [aws-lambda-go](https://github.com/aws/aws-lambda-go) library supports the provided runtimes out of the box. Also, I copied over a lot of the boilerplate (package.json, LICENSE, etc) from the lambda-nodejs package and just did a search and replace, let me know if I got any of it wrong. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
introducing a higher level construct to define golang lambda functions. This was inspired by the other high level constructs for Nodejs and Python I'm setting a couple of things by default. *Environment Variables* * `GOOS=linux` * `GOARCH=amd64` * `GO111MODULE=on` *AssetHashType* * `AssetHashType.OUTPUT` I've added some details in the README on when you could change this to `INPUT`. I'm not really sure what the majority use case would be though. *Go Modules* I am requiring the use of Go modules which were added in Go 1.11 (current version is Go 1.15). I think at this point most Go developers will probably be using Go modules (for a comparison the [aws-sdk-go-v2](https://github.com/aws/aws-sdk-go-v2) requires 1.15) *Runtime* * `Runtime.PROVIDED_AL2` The `GO_1_X` runtime doesn't support newer Lambda features like Lambda extensions, and the [aws-lambda-go](https://github.com/aws/aws-lambda-go) library supports the provided runtimes out of the box. Also, I copied over a lot of the boilerplate (package.json, LICENSE, etc) from the lambda-nodejs package and just did a search and replace, let me know if I got any of it wrong. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
introducing a higher level construct to define golang lambda functions. This was inspired by the
other high level constructs for Nodejs and Python
I'm setting a couple of things by default.
Environment Variables
GOOS=linux
GOARCH=amd64
GO111MODULE=on
AssetHashType
AssetHashType.OUTPUT
I've added some details in the README on when you could change this to
INPUT
. I'm not really sure what the majority use case would be though.Go Modules
I am requiring the use of Go modules which were added in Go 1.11 (current version is Go 1.15). I think at this point most Go developers will probably be using Go modules (for a comparison the aws-sdk-go-v2 requires 1.15)
Runtime
Runtime.PROVIDED_AL2
The
GO_1_X
runtime doesn't support newer Lambda features like Lambda extensions, and the aws-lambda-go library supports the provided runtimes out of the box.Also, I copied over a lot of the boilerplate (package.json, LICENSE, etc) from the lambda-nodejs package and just did a search and replace, let me know if I got any of it wrong.
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license