jaws new: create stages, iam roles, persist data to awsm.json

This commit is contained in:
Austen Collins 2015-08-16 17:23:00 -07:00
parent 7c4e200d57
commit 69fd2ae657

View File

@ -11,16 +11,71 @@
var Promise = require('bluebird'),
fs = Promise.promisifyAll(require('fs')),
os = require('os'),
async = require('async'),
AWS = require('aws-sdk'),
inquirer = require('inquirer'),
chalk = require('chalk'),
jsonfile = Promise.promisifyAll(require('jsonfile')),
shortid = require('shortid');
// AWS IAM Role True Policy
var iamRoleTrustPolicy = JSON.stringify({
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
});
// AWS IAM Role Access Policy
var iamRoleAccessPolicy = JSON.stringify({
"Version": "2012-10-17",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudwatch:*",
"cognito-identity:ListIdentityPools",
"cognito-sync:GetCognitoEvents",
"cognito-sync:SetCognitoEvents",
"dynamodb:*",
"iam:ListAttachedRolePolicies",
"iam:ListRolePolicies",
"iam:ListRoles",
"iam:PassRole",
"kinesis:DescribeStream",
"kinesis:ListStreams",
"kinesis:PutRecord",
"lambda:*",
"logs:*",
"s3:*",
"sns:ListSubscriptions",
"sns:ListSubscriptionsByTopic",
"sns:ListTopics",
"sns:Subscribe",
"sns:Unsubscribe"
],
"Resource": "*"
}
]
});
module.exports = function(JAWS) {
JAWS.new = function() {
var iam = new AWS.IAM();
var project = {};
// Define User Prompts
@ -32,29 +87,45 @@ module.exports = function(JAWS) {
{
type: 'input',
name: 'name',
message: '****** WELCOME TO JAWS: Type a name for your new project (max 20 chars):',
message: '**** WELCOME TO JAWS: Type a name for your new project (max 20 chars):',
default: 'jaws-new-' + shortid.generate()
},
// Request AWS Admin API Key
{
type: 'input',
name: 'awsAdminKeyId',
message: '****** JAWS: Please enter the ACCESS KEY ID for your AWS IAM User:'
message: '**** JAWS: Please enter the ACCESS KEY ID for your AWS IAM User:'
},
// Request AWS Admin API Secret Key
{
type: 'input',
name: 'awsAdminSecretKey',
message: '****** JAWS: Please enter the SECRET ACCESS KEY for your AWS IAM User:'
message: '**** JAWS: Please enter the SECRET ACCESS KEY for your AWS IAM User:'
},
// Request Stages
{
type: 'rawlist',
name: 'stages',
message: '**** JAWS: Which stages would you like to use (you can change later)?',
choices: [
'dev,prod',
'dev,staging,prod',
'dev,staging,test,prod'
]
}
];
inquirer.prompt(prompts, function( answers ) {
// Validate
if (!answers.awsAdminKeyId) return console.log('****** JAWS Error: An AWS Access Key ID is required');
if (!answers.awsAdminSecretKey) return console.log('****** JAWS Error: An AWS Secret Key is required');
// Set and sanitize project info
project.name = answers.name.toLowerCase().trim().replace(/[^a-zA-Z-\d\s:]/g, '').replace(/\s/g, '-').substring(0,19);
project.awsAdminKeyId = answers.awsAdminKeyId.trim();
project.awsAdminSecretKey = answers.awsAdminSecretKey.trim();
project.stages = answers.stages.split(',');
return resolve();
});
@ -63,10 +134,13 @@ module.exports = function(JAWS) {
// Process
userPrompts.then(function(){
// Set project root path. Append unique id if directory already exists.
// Set project root path. Append unique id if name is in use
if (fs.existsSync(JAWS._meta.cwd + '/' + project.name)) {
// Name must be unique or lots of things will break
project.name = project.name + '-' + shortid.generate();
JAWS._meta.projectRootPath = './' + project.name;
} else {
JAWS._meta.projectRootPath = project.name.replace(/\s/g, '-');
}
@ -89,21 +163,6 @@ module.exports = function(JAWS) {
// Create project/front
return fs.mkdirAsync(JAWS._meta.projectRootPath + '/tests');
}).then(function(){
// Create awsm.json
var awsmJson = {
name: project.name,
version: JAWS._meta.version,
type: 'aws_v1',
profile: 'project',
location: '<enter your github repository here>',
cfTemplate: {}
};
jsonfile.spaces = 2;
return jsonfile.writeFile(JAWS._meta.projectRootPath + '/awsm.json', awsmJson);
}).then(function(){
// Create admin.env
@ -116,9 +175,61 @@ module.exports = function(JAWS) {
}).finally(function() {
// End
console.log('******** JAWS: Your project ' + project.name + ' has been successfully created in the current directory.');
// Configure AWS SDK
AWS.config.update({
accessKeyId: project.awsAdminKeyId,
secretAccessKey: project.awsAdminSecretKey
});
// Create IAM Role for each stage
async.eachSeries(project.stages, function(stage, stageCallback) {
// Inform
console.log('****** JAWS: Creating an IAM Role for stage: ' + stage);
var params = {
AssumeRolePolicyDocument: iamRoleTrustPolicy,
RoleName: stage + '_-_' + project.name + '_-_' + 'jaws-role'
};
iam.createRole(params, function(err, data) {
if (err) return console.log(err, err.stack);
project.stages[project.stages.indexOf(stage)] = {
stage: stage,
iamRole: data.Role.RoleName,
iamRoleArn: data.Role.Arn
};
// Inform
console.log('****** JAWS: IAM Role created successfully for stage: ' + stage);
// Callback
return stageCallback();
});
}, function(error) {
// Create awsm.json
var awsmJson = {
name: project.name,
version: JAWS._meta.version,
type: 'aws_v1',
profile: 'project',
author: 'Seymore Serverless <seymore@gmail.com> http://seymore.io',
location: '<enter project\'s github repository url here>',
stages: project.stages,
awsRegions: [ 'us-east-1' ],
cfTemplate: {}
};
jsonfile.spaces = 2;
jsonfile.writeFileSync(JAWS._meta.projectRootPath + '/awsm.json', awsmJson);
// End
console.log('****** JAWS FINISHED: Your project "' + project.name + '" has been successfully created in the current directory.');
});
});
};
};