Rymnel
Rymnel

Reputation: 4515

How do you write to the file system of an aws lambda instance?

I am unsuccessfully trying to write to the file system of an aws lambda instance. The docs say that a standard lambda instance has 512mb of space available at /tmp/. However the following code that runs on my local machine isn't working at all on the lambda instance:

  var fs = require('fs');
  fs.writeFile("/tmp/test.txt", "testing", function(err) {
      if(err) {
          return console.log(err);
      }
      console.log("The file was saved!");
  });

The code in the anonymous callback function is never getting called on the lambda instance. Anyone had any success doing this? Thanks so much for your help.

It's possible that this is a related question. Is it possible that there is some kind of conflict going on between the s3 code and what I'm trying to do with the fs callback function? The code below is what's currently being run.

console.log('Loading function');

var aws = require('aws-sdk');
var s3 = new aws.S3({ apiVersion: '2006-03-01' });
var fs = require('fs');

exports.handler = function(event, context) {
    //console.log('Received event:', JSON.stringify(event, null, 2));

    // Get the object from the event and show its content type
    var bucket = event.Records[0].s3.bucket.name;
    var key = decodeURIComponent(event.Records[0].s3.object.key.replace(/\+/g, ' '));
    var params = {
        Bucket: bucket,
        Key: key
    };
    s3.getObject(params, function(err, data) {
        if (err) {
            console.log(err);
            var message = "Error getting object " + key + " from bucket " + bucket +
            ". Make sure they exist and your bucket is in the same region as this function.";
            console.log(message);
            context.fail(message);
        } else {

            //console.log("DATA: " + data.Body.toString());
            fs.writeFile("/tmp/test.csv", "testing", function (err) {

                if(err) {
                    context.failed("writeToTmp Failed " + err);
                } else {
                    context.succeed("writeFile succeeded");
                }
            });
        }
    });
};

Upvotes: 55

Views: 80141

Answers (3)

onassar
onassar

Reputation: 3558

I ran into this, and it seems like AWS Lambda may be using an older (or modified) version of fs. I figured this out by logging the response from fs.writeFile and noticed it wasn't a promise.

To get around this, I wrapped the call in a promise:

var promise = new Promise(function(resolve, reject) {
    fs.writeFile('/tmp/test.txt', 'testing', function (err) {
        if (err) {
            reject(err);
        } else {
            resolve();
        }
    });
});

Hopefully this helps someone else :hug-emoji:

Upvotes: 1

Rymnel
Rymnel

Reputation: 4515

So the answer lies in the context.fail() or context.succeed() functions. Being completely new to the world of aws and lambda I was ignorant to the fact that calling any of these methods stops execution of the lambda instance.

According to the docs:

The context.succeed() method signals successful execution and returns a string.

By eliminating these and only calling them after I had run all the code that I wanted, everything worked well.

Upvotes: 16

James
James

Reputation: 11931

Modifying your code into the Lambda template worked for me. I think you need to assign a function to exports.handler and call the appropriate context.succeed() or context.fail() method. Otherwise, you just get generic errors.

var fs = require("fs");

exports.handler = function(event, context) {
    fs.writeFile("/tmp/test.txt", "testing", function (err) {
        if (err) {
            context.fail("writeFile failed: " + err);
        } else {
            context.succeed("writeFile succeeded");
        }
    });
};

Upvotes: 23

Related Questions