├── .gitignore ├── CF └── index.js ├── README.md ├── env └── index.js ├── index.js └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | *.seed 2 | *.log 3 | *.csv 4 | *.dat 5 | *.out 6 | *.pid 7 | *.gz 8 | *.idea 9 | *.env 10 | 11 | **/.idea 12 | .DS_Store 13 | .tmp 14 | 15 | # Runtime data 16 | pids 17 | logs 18 | results 19 | npm-debug.log 20 | 21 | node_modules 22 | -------------------------------------------------------------------------------- /CF/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | /** 3 | * Retrieve CloudFormation information within a lambda. 4 | */ 5 | 6 | var Promise = require('bluebird'), 7 | AWS = require('aws-sdk'); 8 | 9 | var CF = { 10 | }; 11 | 12 | /** 13 | * Load CF output variables into environment 14 | */ 15 | CF.loadVars = function () { 16 | // Build CF stack name 17 | if ((!process.env.SERVERLESS_PROJECT_NAME || !process.env.SERVERLESS_STAGE || !process.env.SERVERLESS_REGION)) { 18 | return Promise.reject(new Error("Serverless environment not set")); 19 | } 20 | 21 | var stackName = process.env.SERVERLESS_PROJECT_NAME + "-" + process.env.SERVERLESS_STAGE + "-r"; 22 | return CF._describeCFStack(stackName) 23 | .then(function(stackDescription) { 24 | if (!stackDescription.hasOwnProperty('Outputs') || stackDescription.Outputs.constructor !== Array) { 25 | return Promise.reject(new Error("No outputs in stack description")); 26 | } 27 | 28 | return Promise.each(stackDescription.Outputs, function (outVar) { 29 | process.env["SERVERLESS_CF_" + outVar.OutputKey] = outVar.OutputValue; 30 | return null; 31 | }); 32 | }) 33 | .catch(function (err) { 34 | console.log("WARN: Error retrieving CF variables"); 35 | return Promise.reject(err); 36 | }); 37 | }; 38 | 39 | /** 40 | * Get the CF stack description 41 | */ 42 | CF._describeCFStack = function(stackName) { 43 | return new Promise(function(resolve,reject) { 44 | var cloudformation = new AWS.CloudFormation({apiVersion: '2010-05-15', region: process.env.SERVERLESS_REGION }); 45 | 46 | cloudformation.describeStacks({ StackName: stackName }, function(err, data) { 47 | if (err) { 48 | reject(err); 49 | } 50 | 51 | if (!data || !data.Stacks || data.Stacks.constructor !== Array || data.Stacks.length === 0) { 52 | reject(new Error("invalid response", data)); 53 | } 54 | 55 | // Return only the stack description 56 | resolve(data.Stacks[0]); 57 | }); 58 | }) 59 | }; 60 | 61 | module.exports = CF; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Serverless Helpers (Node.js Version) 2 | ================================= 3 | [![serverless](http://public.serverless.com/badges/v3.svg)](http://www.serverless.com) 4 | 5 | # Currently unmaintained 6 | 7 | At the moment this library is unmaintained, we're going to take another look at it after we've release V1 of the Framework to evaluate how we should support it in the future. 8 | 9 | ###Features 10 | * Helps your modules locate and load Stage Variables that the Serverless framework adds on deployment. 11 | * Allows access to the CF Output variables that you defined in the `s-resources-cf.json` file. 12 | 13 | ## CF Output variables 14 | To have your lambda access the CF output variables you have to give it the `cloudformation:describeStacks` access rights in the lambda IAM role. 15 | 16 | The CF.loadVars() promise will add all CF output variables to the process' 17 | environment as *SERVERLESS_CF_`OutVar name`*. It will add a few ms to the 18 | startup time of your lambda. 19 | 20 | Change your lambda handler as follows: 21 | 22 | ``` 23 | // Require Serverless ENV vars 24 | var ServerlessHelpers = require('serverless-helpers-js'); 25 | ServerlessHelpers.loadEnv(); 26 | 27 | // Require Logic 28 | var lib = require('../lib'); 29 | 30 | // Lambda Handler 31 | module.exports.handler = function(event, context) { 32 | ServerlessHelpers.CF.loadVars() 33 | .then(function() { 34 | lib.respond(event, function(error, response) { 35 | return context.done(error, response); 36 | }); 37 | }) 38 | .catch(function(err) { 39 | return context.done(err, null); 40 | }); 41 | }; 42 | ``` 43 | 44 | -------------------------------------------------------------------------------- /env/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * Find closest .env file. Need to do this because .env is not always at root of project (like during local testing) 5 | */ 6 | 7 | var path = require('path'), 8 | fs = require('fs'); 9 | 10 | function fileExistsSync(path) { 11 | try { 12 | var stats = fs.lstatSync(path); 13 | return stats.isFile(); 14 | } 15 | catch (e) { 16 | return false; 17 | } 18 | } 19 | 20 | var dirName = eval('__dirname'), 21 | i = 0; 22 | 23 | while (i < 6) { 24 | if (fileExistsSync(path.join(dirName, '.env'))) { 25 | break; 26 | } 27 | 28 | dirName = path.join(dirName, '..'); 29 | ++i; 30 | } 31 | 32 | require('dotenv').config({path: path.join(dirName, '.env'), silent: true}); -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Serverless Helpers JS 3 | */ 4 | 5 | var ServerlessHelpers = { 6 | 7 | // Load Environment Variables 8 | loadEnv: function() { 9 | require('./env'); 10 | }, 11 | 12 | // Retrieve CF output variables 13 | // For now has to be called AFTER loadEnv() as we need 14 | // the SERVERLESS variables to compose the CF stack name. 15 | CF: require('./CF'), 16 | 17 | // Shim interacting with Lambda to a callback call 18 | shimCallback: function(method) { 19 | return function (event, context) { 20 | method(event, function (err, val) { 21 | return context.done(err, val); 22 | }); 23 | } 24 | } 25 | 26 | }; 27 | 28 | // Export 29 | module.exports = ServerlessHelpers; 30 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "serverless-helpers-js", 3 | "version": "0.2.1", 4 | "description": "Helper functions for Serverless modules.", 5 | "author": "Austen Collins , Ryan Pendergast , Frank Schmid ", 6 | "license": "MIT", 7 | "main": "index.js", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/serverless/serverless-helpers-js" 11 | }, 12 | "keywords": [ 13 | "serverless", 14 | "serverless modules", 15 | "environment variables", 16 | "lambda", 17 | "api gateway" 18 | ], 19 | "devDependencies": { 20 | "aws-sdk": "^2.2.38" 21 | }, 22 | "dependencies": { 23 | "bluebird": "^3.3.3", 24 | "dotenv": "^1.2.0" 25 | } 26 | } 27 | --------------------------------------------------------------------------------