2016-06-09 16:08:52 +02:00

106 lines
3.3 KiB
JavaScript

'use strict';
const BbPromise = require('bluebird');
const path = require('path');
const lowerFirst = require('lodash').lowerFirst;
const async = require('async');
module.exports = {
create() {
this.serverless.cli.log('Creating Stack...');
const stackName = `${this.serverless.service.service}-${this.options.stage}`;
const params = {
StackName: stackName,
OnFailure: 'DELETE',
Capabilities: [
'CAPABILITY_IAM',
],
Parameters: [],
TemplateBody: JSON.stringify(this.serverless.service.resources.aws),
Tags: [{
Key: 'STAGE',
Value: this.options.stage,
}],
};
return this.CloudFormation.createStackPromised(params);
},
monitorCreate(cfData, frequency) {
const validStatuses = [
'CREATE_COMPLETE',
'CREATE_IN_PROGRESS',
];
return new BbPromise((resolve, reject) => {
let stackStatus = null;
let stackData = null;
async.whilst(
() => (stackStatus !== 'CREATE_COMPLETE'),
(callback) => {
setTimeout(() => {
const params = {
StackName: cfData.StackId,
};
return this.CloudFormation.describeStacksPromised(params)
.then((data) => {
stackData = data;
stackStatus = stackData.Stacks[0].StackStatus;
this.serverless.cli.log('Checking stack creation progress...');
if (!stackStatus || validStatuses.indexOf(stackStatus) === -1) {
return reject(new this.serverless.classes
.Error(`An error occurred while provisioning your cloudformation: ${stackData
.Stacks[0].StackStatusReason}`));
}
return callback();
});
}, frequency || 5000);
},
() => resolve(stackData.Stacks[0]));
});
},
addOutputVars(cfData) {
this.serverless.cli.log('Stack successfully created.');
const serverlessEnvYamlPath = path
.join(this.serverless.config.servicePath, 'serverless.env.yaml');
return this.serverless.yamlParser.parse(serverlessEnvYamlPath).then(parsedServerlessEnvYaml => {
const serverlessEnvYaml = parsedServerlessEnvYaml;
cfData.Outputs.forEach((output) => {
const varName = lowerFirst(output.OutputKey);
const convertedRegion = this.serverless.utils.convertRegionName(this.options.region);
// add vars to memory
this.serverless.service.environment.stages[this.options.stage]
.regions[convertedRegion].vars[varName] = output.OutputValue;
// add vars to file system
serverlessEnvYaml.stages[this.options.stage]
.regions[convertedRegion].vars[varName] = output.OutputValue;
});
this.serverless.utils.writeFileSync(serverlessEnvYamlPath, serverlessEnvYaml);
return BbPromise.resolve();
});
},
createStack() {
const convertedRegion = this.serverless.utils.convertRegionName(this.options.region);
// check if stack is already created
if (this.serverless.service
.getVariables(this.options.stage, convertedRegion).iamRoleArnLambda) {
return BbPromise.resolve();
}
return BbPromise.bind(this)
.then(this.create)
.then(this.monitorCreate)
.then(this.addOutputVars);
},
};