Skip to content

Instantly share code, notes, and snippets.

@ctulek
Last active November 15, 2016 15:49
Show Gist options
  • Save ctulek/6f16352ebdfc166ce905 to your computer and use it in GitHub Desktop.
Save ctulek/6f16352ebdfc166ce905 to your computer and use it in GitHub Desktop.
Gulp File for AWS Lambda

This is a simple gulpfile to compile and upload lambda functions to AWS.

Each lambda function is a separate folder next to gulpfile. Gulp compiles and packages each lambda function as a zip file under "dist" folder.

Gulpfile also puts an ".env" file to each zip package for lambda functions to differentiate between different environments.

See index.js and config.js for the usage of environments.

var convict = require('convict');
var conf = convict({
env: {
doc: "The application environment",
format: ["prod", "dev"],
default: "dev",
env: "ENV" // Received from .env file by dotenv
},
foo: {
default: "val1"
},
bar: {
default: "val2"
}
});
var env = conf.get('env');
// Assumes a config folder
conf.loadFile('./config/' + env + '.json');
conf.validate({strict: true});
module.exports = conf;
var fs = require('fs');
var path = require('path');
var async = require('async');
var argv = require('yargs').argv;
var gulp = require('gulp');
var file = require('gulp-file');
var zip = require('gulp-zip');
var jasmine = require('gulp-jasmine');
var AWS = require('aws-sdk');
// User/Project specific AWS config
var credentials = new AWS.SharedIniFileCredentials({profile: 'capi'});
AWS.config.credentials = credentials;
AWS.config.region = 'us-east-1';
// config - end
var iam = new AWS.IAM();
var lambda = new AWS.Lambda();
/**
* Returns the user used to access AWS. Used for debugging purposes
**/
gulp.task('whoami', function (done) {
iam.getUser(function (err, data) {
if (err) console.error(err);
else console.log(JSON.stringify(data, null, '\t'));
done();
});
});
/**
* Lists all functions registered on AWS Lambda for the given region
*/
gulp.task('list-functions', function (done) {
lambda.listFunctions(function (err, data) {
if (err) console.error(err);
else console.log(JSON.stringify(data, null, '\t'));
done();
});
});
/**
* Compile lambda function in the given directory and put to dist folder
* Expects the --function command line argument and optional --environment command line argument
*
* This task also adds a .env file to the zip file indicating the environment that can be used by dotenv
*
* This task is usually called by update-lambda task
*/
gulp.task('compile-lambda', ['install'], function () {
var name = argv.function;
var env = argv.environment || 'dev';
return gulp.src(name + '/**/*')
.pipe(file('.env', 'ENV=' + env))
.pipe(zip(name + '.zip'))
.pipe(gulp.dest('dist'));
});
/**
* Update the code of the AWS lambda function in the given function directory.
* The function directory is set by using --function command line parameter.
*
* If the optional --environment command line argument is given and if it is equal to 'prod'
* update-lambda task also creates a new version on AWS Lambda.
*
* This task will first run tests and it will fail if any test fails
*
*/
gulp.task('update-lambda', ['test', 'compile-lambda'], function (done) {
var name = argv.function;
var env = argv.environment || 'dev';
var params = {
FunctionName: name,
Publish: env == 'prod'
};
fs.readFile('dist/' + name + '.zip', function (err, data) {
params['ZipFile'] = data;
lambda.updateFunctionCode(params, function (err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
done();
});
});
});
/**
* Runs Jasmine tests defined in every file ending with '.test.js'
*/
gulp.task('test', ['install'], function () {
var name = argv.function || '.';
return gulp.src([name + '/**/*.test.js', '!node_modules/**', '!dist/**'])
.pipe(jasmine())
});
gulp.task('install', function (done) {
var names = argv.function;
names = names ? [names] :
getFolders('.')
.filter(function (folder) {
return [
'dist',
'node_modules'
].indexOf(folder) == -1
&& folder[0] != '.'
});
async.each(names, function(name, done) {
console.log('npm install for ' + name);
var exec = require('child_process').exec;
var cmd = 'cd ./' + name + '; npm install';
exec(cmd, function (err, stdout, stderr) {
stdout && console.log(stdout);
stderr && console.log(stderr);
done();
});
}, done);
});
function getFolders(dir) {
return fs.readdirSync(dir)
.filter(function (file) {
return fs.statSync(path.join(dir, file)).isDirectory();
});
}
// Example lambda index.js
require('dotenv').load();
var conf = require('./config.js');
exports.handler = function (event, context) {
// ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment