lifadev / archive_aws-lambda-go

A fast and clean way to execute Go on AWS Lambda.
https://github.com/eawsy/aws-lambda-go
Apache License 2.0
699 stars 36 forks source link

Filename other than handler.so #5

Closed danilobuerger closed 7 years ago

danilobuerger commented 7 years ago

Is it possible to somehow use a different filename other than handler.so?

If I want to provision the lambda first with cloudformation, I could use something like:

Lambda:
  Type: AWS::Lambda::Function
  Properties:
    Runtime: python2.7
    Handler: index.handler
    Role: !GetAtt LambdaExecutionRole.Arn
    Code:
      ZipFile: |
        def handler(event, context): return

If I now replace the code, I would have to change the handler too.

fsenart commented 7 years ago

Hi,

It is not possible to change the binary name. It has to be handler.so as this name is the name of the final low-level Python C extension used by AWS Lambda.

But, @eawsy we use CloudFormation all the time and here is an example of snippet to deploy Lambda functions build with this project:

Lambda:
  Type: AWS::Lambda::Function
  Properties:
    Code:
      S3Bucket: you_s3_bucket
      S3Key: handler.zip  # <===== package containing handle.so
    Role: !GetAtt [LambdaExecutionRole, Arn]
    Handler: handler.handle
    Runtime: python2.7
    MemorySize: 128
    Timeout: 1

What you are doing with your CloudFormation is inlining your code in the CF template. This is only possible with script languages as languages like Go (or even the officially supported Java) need a compilation step.

More generally, independently from your request, I don't encourage you to inline your business code in the CloudFormation template.

danilobuerger commented 7 years ago

I don't think you understood my use case correctly. I am using the cloudformation template to bootstrap the whole thing first. So there is no business logic in the template. While doing continuous deploys, I would like to use the aws cli to update the code of the created lambda on every deploy. I don't want to upload it to s3. So in theory, the code thats created via cloudformation doesn't have to do anything meaningful or even work, but it would be nicer if it did.

I don't know much about cgo, but in general, I can use ldflags -X on go build to change a variable. Wouldn't it be possible to change the inithandler "handler" string in proxy.c on build with some flag?

fsenart commented 7 years ago

Ok, now I see perfectly your use case. Amazing.

First, to be honest, we already have tried to change the way the handler name is set several times. But it is a very complex subject to make it dynamic. And to answer your question about ldflags -X, it can't do the job. I see what you mean but this flag can't (even used with a lot of hacks :)) change this function name which defines the name of the module.

I see one immediate solution for your use case: Change the proxy.c and add a #ifdef, #else, #endif block in order to duplicate the module initialization code (base on gcc build flags) and offer the possibility to have "index" as the second naming option (as I've explained it can't be dynamic).

Let us see if we can find a more elegant solution.

PS: When releasing the project we've decided that the name should be "handler" but if I knew your use case, trust me the name would be "index" :). Now after a few days, we already have legacy code.

danilobuerger commented 7 years ago

I know the feeling. It's a shame that cloudformation doesn't allow specifying a name for the Zipfile prop.

Thinking about it, I don't see another use case (except for cloudformation) where the handler must have a different name. So I guess having the option for it to be either handler or index would cover 99 % 💃 .

fsenart commented 7 years ago

Yes, it's my feeling too. Let me a few hours to see if I can find another solution, if not I will proceed as described above ;)

fsenart commented 7 years ago

Ok, I've implemented the ultimate solution with dynamic naming for the function and the handler. I will commit changes (fully backward compatible with the existing solution) in a few minutes. But to unlock your particular problem, I have to know if you use OSX? if yes I have to provide you information for building before I can update the documentation.

danilobuerger commented 7 years ago

Awesome. Well, I do use a mac, but I would build it inside a docker container.

fsenart commented 7 years ago

So for now, you have to execute the following commands to build and package:

go build -buildmode=c-shared -ldflags="-w -s" -o handler.so
zip handler.zip handler.so

after the commit you have to do:

CGO_CFLAGS='-DFUNCTION=index -DHANDLER=handle' go build -buildmode=c-shared -ldflags="-w -s" -o index.so
zip handler.zip index.so

If you omit any of the CGO_CFLAGS, then it will take the current default. DO NOT forget to change the output filename to index.so and if you have an existing handler.zip in your working directory then delete it before using this new version.

It is ok for you? If yes I will update the repo.

danilobuerger commented 7 years ago

Sounds good to me 💯

fsenart commented 7 years ago

Done! PS: in the comment I wrote CGO_FLAGS, it was a mistake, it is CGO_CFLAGS.

danilobuerger commented 7 years ago

Works as expected. Thanks!

josegonzalez commented 7 years ago

@fsenart is this documented somewhere, and would this allow the same golang project to power multiple lambda jobs with separate handlers?

danilobuerger commented 7 years ago

+1 for documentation

@josegonzalez the same golang project, yes. But not the same build as you would specify the handler per build.

fsenart commented 7 years ago

@josegonzalez We are trying to revamp the documentation in order to have all questions asked during the last week answered. This is not an easy task, some people need advanced topics and others more conventional ones. Please keep connected and if you have any suggestion, its very welcome.

Moreover, as @danilobuerger states, THIS project goal is to provide a thin and a very concise layer to overcome ONLY the lack of official golang support in Lambda. Also, it doesn't provide multiple handlers. Just one build with one handler. But we are also working to open source (in the coming weeks) more tools in other projects to provide more high-level tools to the community. And help/suggestions are welcome.

danilobuerger commented 7 years ago

btw. you could just use one binary for multiple lambdas if in your handler you select the appropriate subhandler based on the provided lambda context.

josegonzalez commented 7 years ago

@fsenart no doubt, just trying to figure out how to use this project. It seems super-awesome and I'm excited to get started. Godocs are a good start! As soon as you all push out something like readthedocs or viewdocs.io, I'll def try and contribute back :)

fsenart commented 7 years ago

@danilobuerger @josegonzalez, @lsuss and me have revamped all the documentation during the past 3 days. Take a tour at the new README and the wiki. There is also a brand new Docker image with an integrated CLI and all options discussed in this issue available for customization. Please join also the Gitter channel to not abuse this issue :) Do not hesitate to take us informed about your feeling around this new documentation.