Search code examples
amazon-web-servicesrustaws-lambdarust-cargo

Invoking binary in aws lambda with rust


So I have the following rust aws lambda function:

use std::io::Read;
use std::process::{Command, Stdio};
use lambda_http::{run, service_fn, Body, Error, Request, RequestExt, Response};
use lambda_http::aws_lambda_events::serde_json::json;

/// This is the main body for the function.
/// Write your code inside it.
/// There are some code example in the following URLs:
/// - https://github.com/awslabs/aws-lambda-rust-runtime/tree/main/examples
async fn function_handler(_event: Request) -> Result<Response<Body>, Error> {
    // Extract some useful information from the request
    let program = Command::new("./myProggram")
        .stdout(Stdio::piped())
        .output()
        .expect("failed to execute process");

    let data = String::from_utf8(program.stdout).unwrap();
    let parsed = data.split("\n").filter(|x| !x.is_empty()).collect::<Vec<&str>>();

    // Return something that implements IntoResponse.
    // It will be serialized to the right response event automatically by the runtime
    let resp = Response::builder()
        .status(200)
        .header("content-type", "application/json")
        .body(json!(parsed).to_string().into())
        .map_err(Box::new)?;
    Ok(resp)
}

#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::INFO)
        // disable printing the name of the module in every log line.
        .with_target(false)
        // disabling time is handy because CloudWatch will add the ingestion time.
        .without_time()
        .init();

    run(service_fn(function_handler)).await
}

The idea here is that I want to return the response from the binary in JSON format.

I'm compiling the function with cargo lambda which is producing bootstrap file, then I'm zipping it manually by including the bootstrap binary and the myProgram binary.

When I test my function in the lambda panel by sending event to it I get the response with the right headers etc. but the response body is empty. I'm deploying my function thru the aws panel, on Custom runtime on Amazon Linux 2 by uploading the zip file.

When I test locally with cargo lambda watch and cargo lambda invoke the response body is filled with the myProgram stdout parsed to json.

Any ideas or thoughts on what goes wrong in the actual cloud are much appreciated!


Solution

  • My problem was with the dynamically linked libraries in the binary. It is actually python binary and it was missing specific version of GLIBC. The easiest solution in my case was to compile myProgram on Amazon Linux 2