Search code examples
node.jsamazon-web-servicesaws-lambdaspawn

Capturing output from process spawned from NodeJS Lambda


I'm trying to capture the output from an external program launched from an AWS Lambda written in NodeJS. Full example code below. Any test event would do since it's not really used.

exports.handler = async (event) => {
    console.log ("Entering lambda" + JSON.stringify(event))

    var spawn = require('child_process').spawnSync;

    child_process = spawn ('aws', [' --version'], {
        stdio: 'inherit',
        stderr: 'inherit',
        shell: true
    })

    console.log ("done");
    const response = {
        statusCode: 200,
        body: JSON.stringify('done'),
    };
    return response;
};

When I run it, I get the following as output (I removed the test event details for brevity, since it's irrelevant).

What I don't see is the results of the aws --version command that I expected (I'm using it to test the correct invocation of the AWS CLI, but any Linux command would do). The code does execute synchronously because if I replace the invocation with child_process = spawn ('sleep', ['1'], {, lambda's execution time grows to 1117.85 ms, so the one-second sleep happens. But there's nothing captured in the execution logs.

START RequestId: 0c1287e2-d2ee-4436-a577-bc8ec3608120 Version: $LATEST
2019-01-16T19:12:45.130Z    0c1287e2-d2ee-4436-a577-bc8ec3608120    Entering lambda {...}
2019-01-16T19:12:45.143Z    0c1287e2-d2ee-4436-a577-bc8ec3608120    done
END RequestId: 0c1287e2-d2ee-4436-a577-bc8ec3608120
REPORT RequestId: 0c1287e2-d2ee-4436-a577-bc8ec3608120  Duration: 13.29 ms  Billed Duration: 100 ms     Memory Size: 128 MB Max Memory Used: 20 MB  

Am I doing something wrong? Or is there any other way to capture the output (status code, stdio, stderr) for a Lambda written in NodeJS?


Solution

  • This works for me (node.js 8.10 runtime)

    
    exports.handler = async (event) => {
        const spawnSync = require('child_process').spawnSync;
        const process = spawnSync('echo', ['hello', 'world'], {
            stdio: 'pipe',
            stderr: 'pipe'
        });
        console.log(process.status);
        console.log(process.stdout.toString());
    };
    

    When trying to run with aws, it throws a ENOENT error. In other words, the command is not available. As mentioned in the question comments by @jarmod, I also believe the awscli is not available in the Lambda container.

    What is available is the SDK, so that you can require('aws-sdk'); without bundling it to your Lambda deployment package.