srijs / rust-aws-lambda

Support for running Rust programs on AWS Lambda
https://srijs.github.io/rust-aws-lambda
MIT License
319 stars 17 forks source link

Document building the rust zip #22

Closed insanitybit closed 6 years ago

insanitybit commented 6 years ago

I'm curious about how to build the Rust lambda package, I don't see this documented.

Is there an awscli command I could run?

oceanlewis commented 6 years ago

There's a few ways to build. If you have access to Cloud9 or an Amazon Linux server you can build there for that host system. What I did was I ended up using rust-musl-builder to build inside a docker image on my macbook while targeting x86_64-unknown-linux-musl so that my build is statically linked. After that you can test with the aws-sam-cli to make sure you've got something working or just upload to Lambda and run it directly in the console.

insanitybit commented 6 years ago

I'll give that a try. If I get something working I'll see about contributing to the readme. Thank you.

oceanlewis commented 6 years ago

You bet! There's definitely multiple ways to go about it, which is probably why the authors have left that section blank.

LegNeato commented 6 years ago

I've been holding off on documenting this because it isn't clear what the best way is for most people, we don't want to be in the business of keeping up with docker and cross compiling best practices, and there is no lambda-specific magic above and beyond what you would do for a normal rust binary and a different target system.

That being said, it looks like https://github.com/japaric/cross is pretty decent and might be the most rust-centric way to recommend.

LegNeato commented 6 years ago

https://github.com/srijs/rust-aws-lambda/issues/21 also has an example using docker and a makefile

oceanlewis commented 6 years ago

In the requirements for cross, "A Linux kernel with binfmt_misc support is required for cross testing." is listed. I haven't used it, but it sounds like it's a Linux-specific tool.

insanitybit commented 6 years ago

To be honest, even if the docs said "Once you have a binary, you run these awscli commands" that'd be helpful, and then perhaps link to some ways to build those binaries but not necessarily. I have not used aws lambda myself, so this is actually my first time using any of the tools.

insanitybit commented 6 years ago

I was able to get this working with SAM by utilizing the musl docker container that @davidarmstronglewis provided, and guessing/ poking a SAM template. I can either write this up for the README at some point or, if you don't want to track it, I'll probably just publish a blog post on the matter.

LegNeato commented 6 years ago

Awesome! FWIW, I've also started an optional cargo subcommand binary to hopefully make this trivial in the future.

sporto commented 6 years ago

@insanitybit do you have an example repo? I'm trying to use this with SAM.

sporto commented 6 years ago

I was able to make it work with SAM here https://github.com/sporto/lambda-rust-example Missing the zip part

insanitybit commented 6 years ago

No, I don't have a repo.

I basically did:

alias rust-musl-builder='docker run --rm -it -v "$(pwd)":/home/rust/src ekidd/rust-musl-builder'
rust-musl-builder cargo build --release

I ran this in my project 'aws-test'.

I then copied the file at ./target/x86_64-unknown-linux-musl/release/aws-test to the project root.

I zip'd the file to aws-test.zip

I then created a local template.yml:

Resources:
    MySQSQueueFunction:
      Type: AWS::Serverless::Function
      Properties:
        Handler: aws-test
        CodeUri: ./aws-test.zip
        Runtime: go1.x
        Events:
          MySQSEvent:
            Type: SQS
            Properties:
              Queue: !GetAtt MySqsQueue.Arn
              BatchSize: 10

    MySqsQueue:
      Type: AWS::SQS::Queue

And ran sam local invoke --event event with an event that I had generated.

Note that this is for a lambda that takes SqsEvent's, as defined by the lambda crate.

patrick-bruckner commented 6 years ago

Has anyone gotten this to successfully build using rust-musl-builder on Docker for Windows? It seems to work great on Linux, but when I run it on Windows I get an error when trying to compile lazy_static

/usr/bin/ld: cannot find /home/rust/src/target/release/deps/libversion_check-8922b6a13e5d049e.rlib: No such file or directory
    collect2: error: ld returned 1 exit status

The file is definitely there though.

rust@154dfa39d57c:~/src$ ls -l /home/rust/src/target/release/deps/ | grep "libversion*"
-rwxrwxrwx 1 root root  219606 Aug 29 03:34 libversion_check-8922b6a13e5d049e.rlib
dbcfd commented 6 years ago

https://github.com/srijs/rust-aws-lambda/pull/25

rocallahan commented 6 years ago

It would be good to document somewhere that if you're already building on Linux, you don't need to build inside a Docker container. Instead you can build directly with cargo --target x86_64-unknown-linux-musl (even if you're not running Amazon Linux), which can be much simpler and faster.

LegNeato commented 6 years ago

@rocallahan good point, I'll push a readme change tomorrow if someone doesn't beat me to it

dbcfd commented 6 years ago

One slight gotcha to that is that you have to build libraries (e.g. OpenSSL) against musl as well.

If your lambda depends purely on rust code, the musl target is easiest. If you have dependencies, you'll probably want to use docker just to keep existing libraries separate from musl libs.

rocallahan commented 6 years ago

True, but rusoto recently added support for rustls, which works fine with AWS, so it's getting easier to avoid OpenSSL completely.

dbcfd commented 6 years ago

Nice. I figured rusoto would be used a bit with this, so glad that's one less hurdle to overcome for people building.

LegNeato commented 6 years ago

Added notes about Linux as well as the rustls feature in rusoto in https://github.com/srijs/rust-aws-lambda/commit/a5d630479ba5e309d1425e84099332e70204ecc3. I'm going to close this out and additional changes and improvements can be handled in new issues.