Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ $ node-lambda deploy --help

## Custom Environment Variables

AWS Lambda doesn't let you set environment variables for your function, but in many cases you will need to configure your function with secure values that you don't want to check into version control, for example a DB connection string or encryption key. Use the sample `deploy.env` file in combination with the `--configFile` flag to set values which will be prepended to your compiled Lambda function as `process.env` environment variables before it gets uploaded to S3.
AWS Lambda will let you set environment variables for your function. Use the sample `deploy.env` file in combination with the `--configFile` flag to set values which will be added to the lambda configuration upon deploy. Environment variables will also be set when running locally using the same flag

## Node.js Runtime Configuration

Expand Down
60 changes: 14 additions & 46 deletions lib/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,10 @@ Lambda.prototype._params = function (program, buffer) {
MemorySize: program.memorySize,
Timeout: program.timeout,
Publish: program.publish,
VpcConfig: {}
VpcConfig: {},
Environment: {
Variables: {}
}
};
if (program.lambdaVersion) {
params.FunctionName += ('-' + program.lambdaVersion);
Expand All @@ -133,7 +136,14 @@ Lambda.prototype._params = function (program, buffer) {
'SecurityGroupIds': program.vpcSecurityGroups.split(',')
};
}

if (program.configFile) {
var configValues = fs.readFileSync(program.configFile);
var config = dotenv.parse(configValues);
params.Environment = {
Variables: config
}
}

return params;
};

Expand Down Expand Up @@ -276,41 +286,6 @@ Lambda.prototype._cleanDirectory = function (codeDirectory, callback) {
});
};

Lambda.prototype._setEnvironmentVars = function (program, codeDirectory) {
console.log('=> Setting "environment variables" for Lambda from %s', program.configFile);
// Which file is the handler?
var handlerFileName = codeDirectory + '/' + program.handler.split('.').shift() + '.js';
var contents = fs.readFileSync(handlerFileName);

var configValues = fs.readFileSync(program.configFile);
var prefix = '////////////////////////////////////\n// "Environment Variables"\n';
var config = dotenv.parse(configValues);
var contentStr = contents.toString();

if(program.environment) {
prefix += 'process.env["environment"]=' + JSON.stringify(program.environment) + ';\n';
}

for (var k in config) {
if (!config.hasOwnProperty(k)) {
continue;
}

// Use JSON.stringify to ensure that it's valid code.
prefix += 'process.env["' + k + '"]=' + JSON.stringify(config[k]) + ';\n';
}
prefix += '////////////////////////////////////\n\n';

// If the first line of the file is 'use strict', append after
if (contentStr.trim().indexOf('use strict') === 1) {
contentStr = contentStr.replace(/([`'"]use strict[`'"][;]?)/, '$1\n' + prefix);
} else {
contentStr = prefix + contentStr;
}

fs.writeFileSync(handlerFileName, contentStr);
};

Lambda.prototype._setRunTimeEnvironmentVars = function (program) {
var configValues = fs.readFileSync(program.configFile);
var config = dotenv.parse(configValues);
Expand Down Expand Up @@ -341,7 +316,8 @@ Lambda.prototype._uploadExisting = function (lambda, params, cb) {
'MemorySize': params.MemorySize,
'Role': params.Role,
'Timeout': params.Timeout,
'VpcConfig': params.VpcConfig
'VpcConfig': params.VpcConfig,
'Environment': params.Environment
}, function (err, data) {
return cb(err, data);
});
Expand All @@ -368,10 +344,6 @@ Lambda.prototype._archivePrebuilt = function (program, archive_callback) {
return archive_callback(err);
}

// Add custom environment variables if program.configFile is defined
if (program.configFile) {
_this._setEnvironmentVars(program, codeDirectory);
}
console.log('=> Zipping deployment package');
var archive = process.platform !== 'win32' ? _this._nativeZip : _this._zip;
archive = archive.bind(_this);
Expand Down Expand Up @@ -415,10 +387,6 @@ Lambda.prototype._buildAndArchive = function (program, archive_callback) {
return archive_callback(err);
}

// Add custom environment variables if program.configFile is defined
if (program.configFile) {
_this._setEnvironmentVars(program, codeDirectory);
}
console.log('=> Zipping deployment package');

var archive = process.platform !== 'win32' ? _this._nativeZip : _this._zip;
Expand Down
77 changes: 23 additions & 54 deletions test/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,29 @@ describe('node-lambda', function () {
var params = lambda._params(program);
assert.equal(Object.keys(params.VpcConfig).length, 0);
});

describe('configFile', function () {
beforeEach(function () {
// Prep...
fs.writeFileSync('tmp.env', 'FOO=bar\nBAZ=bing\n');
});

afterEach(function () {
fs.unlinkSync('tmp.env');
});

it('adds variables when configFile param is set', function () {
program.configFile = 'tmp.env';
var params = lambda._params(program);
assert.equal(params.Environment.Variables['FOO'], "bar");
assert.equal(params.Environment.Variables['BAZ'], "bing");
});

it('does not add when configFile param is not set', function () {
var params = lambda._params(program);
assert.equal(Object.keys(params.Environment.Variables).length, 0);
});
});
});

describe('_zipfileTmpPath', function () {
Expand Down Expand Up @@ -329,33 +352,6 @@ describe('node-lambda', function () {
});
});

describe('environment variable injection', function () {
beforeEach(function () {
// Prep...
fs.writeFileSync('tmp.env', 'FOO=bar\nBAZ=bing\n');
fs.writeFileSync('test.js', '');
});

afterEach(function () {
fs.unlinkSync('tmp.env');
fs.unlinkSync('test.js');
});

it('should inject environment variables at the top of the entry point file', function () {

// Run it...
lambda._setEnvironmentVars({
configFile: 'tmp.env',
handler: 'test.handler',
}, process.cwd());

assert.equal(fs.readFileSync('test.js').toString(), '////////////////////////////////////\n' +
'// "Environment Variables"\nprocess.env["FOO"]="bar";\n' +
'process.env["BAZ"]="bing";\n////////////////////////////////////\n\n');
});

});

describe('environment variable injection at runtime', function () {
beforeEach(function () {
// Prep...
Expand All @@ -379,33 +375,6 @@ describe('node-lambda', function () {

});

describe('environment variable injection - "use strict" allowance', function () {
beforeEach(function () {
// Prep...
fs.writeFileSync('tmp.env', 'FOO=bar\nBAZ=bing\n');
fs.writeFileSync('test.js', '\'use strict\';');
});

afterEach(function () {
fs.unlinkSync('tmp.env');
fs.unlinkSync('test.js');
});

it('should inject environment variables at the top of the entry point file', function () {

// Run it...
lambda._setEnvironmentVars({
configFile: 'tmp.env',
handler: 'test.handler',
}, process.cwd());

assert.equal(fs.readFileSync('test.js').toString(), '\'use strict\';\n////////////////////////////////////\n' +
'// "Environment Variables"\nprocess.env["FOO"]="bar";\n' +
'process.env["BAZ"]="bing";\n////////////////////////////////////\n\n');
});

});

describe('create sample files', function () {

afterEach(function () {
Expand Down