Skip to content

Commit dcc33ea

Browse files
authored
Expanded README on how to build for Amazon Linux 2 x86 or ARM, includ… (#360)
* Expanded README on how to build for Amazon Linux 2 x86 or ARM, including instructions for compiling on MacOS * Fixed misses in PR * Update README.md
1 parent 2dca015 commit dcc33ea

File tree

1 file changed

+55
-8
lines changed

1 file changed

+55
-8
lines changed

README.md

+55-8
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,66 @@ async fn func(event: Value, _: Context) -> Result<Value, Error> {
2929
}
3030
```
3131

32-
The code above is the same as the [basic example](https://github.com/awslabs/aws-lambda-rust-runtime/blob/master/lambda-runtime/examples/basic.rs) in the `lambda_runtime` crate.
33-
3432
### Deployment
3533

3634
There are currently multiple ways of building this package: manually with the AWS CLI, and with the [Serverless framework](https://serverless.com/framework/).
3735

3836
#### AWS CLI
3937

40-
To deploy the basic sample as a Lambda function using the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html), we first need to manually build it with [`cargo`](https://doc.rust-lang.org/cargo/). Since Lambda uses Amazon Linux, you'll need to target your executable for an `x86_64-unknown-linux-musl` platform.
38+
To deploy the basic sample as a Lambda function using the [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html), we first need to manually build it with [`cargo`](https://doc.rust-lang.org/cargo/). Due to a few differences in dependencies, the process for building for Amazon Linux 2 is slightly different than building for Amazon Linux.
39+
40+
**Building for Amazon Linux 2**
41+
42+
Decide which target you'd like to use. For ARM Lambda Functions you'll want to use `aarch64-unknown-linux-gnu` and for x86 Lambda Functions you'll want to use `x86_64-unknown-linux-gnu`.
43+
44+
Run this script once to add your desired target, in this example we'll use x86:
45+
46+
```bash
47+
$ rustup target add x86_64-unknown-linux-gnu
48+
```
49+
50+
Compile one of the examples as a _release_ with a specific _target_ for deployment to AWS:
51+
52+
```bash
53+
$ cargo build -p lambda_runtime --example basic --release --target x86_64-unknown-linux-gnu
54+
```
55+
56+
_Building on MacOS Using Docker_
57+
58+
At the time of writing, the ability to cross compile to x86 or aarch64 AL2 on MacOS is limited. The most robust way we've found is using Docker to produce the artifacts for you. This guide will work for both Intel and Apple Silicon MacOS and requires that you have set up Docker correctly for either architecture. [See here for a guide on how to do this.](https://docs.docker.com/desktop/mac/install/)
59+
60+
The following command will pull the [official Rust Docker Image](https://hub.docker.com/_/rust) for a given architecture you plan to use in Lambda and use it to run any cargo commands you need, such as build.
61+
62+
```bash
63+
$ LAMBDA_ARCH="linux/arm64" # set this to either linux/arm64 for ARM functions, or linux/amd64 for x86 functions.
64+
$ RUST_TARGET="aarch64-unknown-linux-gnu" # corresponding with the above, set this to aarch64 or x86_64 -unknown-linux-gnu for ARM or x86 functions.
65+
$ RUST_VERSION="latest" # Set this to a specific version of rust you want to compile for, or to latest if you want the latest stable version.
66+
$ docker run \
67+
--platform ${LAMBDA_ARCH} \
68+
--rm --user "$(id -u)":"$(id -g)" \
69+
-v "${PWD}":/usr/src/myapp -w /usr/src/myapp rust:${RUST_VERSION} \
70+
cargo build -p lambda_runtime --example basic --release --target ${RUST_TARGET} # This line can be any cargo command
71+
```
72+
73+
In short, the above command does the following:
74+
75+
1. Gives the current user ownership of the artifacts produced by the cargo run.
76+
2. Mounts the current working directory as a volume within the pulled Docker image.
77+
3. Pulls a given Rust Docker image for a given platform.
78+
4. Executes the command on the line beginning with `cargo` within the project directory within the image.
79+
80+
It is important to note that build artifacts produced from the above command can be found under the expected `target/` directory in the project after build.
81+
82+
**Building for Amazon Linux 1**
4183

4284
Run this script once to add the new target:
4385
```bash
4486
$ rustup target add x86_64-unknown-linux-musl
4587
```
4688

89+
* **Note:** If you are running on Mac OS you'll need to install the linker for the target platform. You do this using the `musl-cross` tap from [Homebrew](https://brew.sh/) which provides a complete cross-compilation toolchain for Mac OS. Once `musl-cross` is installed we will also need to inform cargo of the newly installed linker when building for the `x86_64-unknown-linux-musl` platform.
90+
4791

48-
* **Note:** If you are running on Mac OS you'll need to install the linker for the target platform. You do this using the `musl-cross` tap from [Homebrew](https://brew.sh/) which provides a complete cross-compilation toolchain for Mac OS. Once `musl-cross` is installed we will also need to inform cargo of the newly installed linker when building for the `x86_64-unknown-linux-musl` platform.
4992
```bash
5093
$ brew install filosottile/musl-cross/musl-cross
5194
$ mkdir .cargo
@@ -57,10 +100,14 @@ Compile one of the examples as a _release_ with a specific _target_ for deployme
57100
$ cargo build -p lambda_runtime --example basic --release --target x86_64-unknown-linux-musl
58101
```
59102

103+
**Uploading the Resulting Binary to Lambda**
104+
60105
For [a custom runtime](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-custom.html), AWS Lambda looks for an executable called `bootstrap` in the deployment package zip. Rename the generated `basic` executable to `bootstrap` and add it to a zip archive.
61106

107+
NOTE: Depending on the target you used above, you'll find the provided basic executable under the corresponding directory. In the following example, we've compiled for x86_64-unknown-linux-gnu.
108+
62109
```bash
63-
$ cp ./target/x86_64-unknown-linux-musl/release/examples/basic ./bootstrap && zip lambda.zip bootstrap && rm bootstrap
110+
$ cp ./target/x86_64-unknown-linux-gnu/release/examples/basic ./bootstrap && zip lambda.zip bootstrap && rm bootstrap
64111
```
65112

66113
Now that we have a deployment package (`lambda.zip`), we can use the [AWS CLI](https://aws.amazon.com/cli/) to create a new Lambda function. Make sure to replace the execution role with an existing role in your account!
@@ -69,7 +116,7 @@ Now that we have a deployment package (`lambda.zip`), we can use the [AWS CLI](h
69116
$ aws lambda create-function --function-name rustTest \
70117
--handler doesnt.matter \
71118
--zip-file fileb://./lambda.zip \
72-
--runtime provided \
119+
--runtime provided.al2 \ # Change this to provided.al if you would like to use Amazon Linux 1.
73120
--role arn:aws:iam::XXXXXXXXXXXXX:role/your_lambda_execution_role \
74121
--environment Variables={RUST_BACKTRACE=1} \
75122
--tracing-config Mode=Active
@@ -79,9 +126,9 @@ You can now test the function using the AWS CLI or the AWS Lambda console
79126

80127
```bash
81128
$ aws lambda invoke --function-name rustTest \
82-
--payload '{"firstName": "world"}' \
129+
--payload '{"command": "Say Hi!"}' \
83130
output.json
84-
$ cat output.json # Prints: {"message": "Hello, world!"}
131+
$ cat output.json # Prints: {"msg": "Command Say Hi! executed."}
85132
```
86133

87134
**Note:** `--cli-binary-format raw-in-base64-out` is a required

0 commit comments

Comments
 (0)