lib/questions.js
(function() {
'use strict';
var regexes = require('./regexes');
function validateInput(value, regex, errorMessage) {
var isMatch = value.match(regex);
if (isMatch) { return true; }
return errorMessage;
}
function appendTagDefaultValue(answers, tagName) {
return answers.appName + tagName;
}
function prependTagDefaultValue(answers, tagName) {
return tagName + answers.appName;
}
function setInstanceSizeQuestion(answers) {
return 'Which of the following ' + answers.familyChoice + ' instance sizes would you like?';
}
var questions = [
{
type: 'input',
name: 'appName',
message: function() {
// This clears the screen
process.stdout.write('\u001b[2J\u001b[0;0H');
return 'What is the name of your application?';
},
default: 'myApp'
}, {
type: 'list',
name: 'region',
message: 'In which region will it run?',
default: 'us-east-1',
// @TODO (1) change to 'US East (N. Virginia): us-east-1'
// @TODO (2) filter answer so that 'region' variable only gets 'us-east-1'
choices: [
'us-east-1',
'us-west-1',
'us-west-2',
'us-gov-west-1',
'eu-west-1',
'eu-central-1',
'ap-southeast-1',
'ap-southeast-2',
'ap-southeast-3',
'sa-east-1'
]
}, {
type: 'list',
name: 'aws_zone',
message: 'Within the region, in which zone will it run?',
default: 'b',
// @TODO (1) discover the zone choices of each specific region
// @TODO (2) based on the region variable, give different choice lists
choices: [
'a',
'b',
'c',
'd',
'e',
'f'
]
}, {
type: 'list',
name: 'familyChoice',
message: 'Please note the following about instance types:\n\n' +
' T2, M3, and M4 are general purpose.\n' +
' C3 and C4 are compute optimized.\n' +
' R3 is memory optimized.\n' +
' G2 is GPU optimized.\n' +
' I2 and D2 are storage optimized.\n' +
' I2 is for high I/O.\n' +
' D2 is for dense storage.\n\n' +
' For more information on instance types,\n' +
' please see https://aws.amazon.com/ec2/instance-types/\n\n' +
' Now you must choose an instance type from a given family.\n' +
' Which family do you choose?',
default: 'T2',
choices: [
'T2',
'M3',
'M4',
'C3',
'C4',
'R3',
'G2',
'I2',
'D2'
]
}, {
type: 'list',
name: 'instance_type',
message: function(answers) {
return setInstanceSizeQuestion(answers);
},
default: 't2.micro',
choices: [
't2.micro',
't2.small',
't2.medium',
't2.large'
],
when: function(answers) {
return answers.familyChoice === 'T2';
}
}, {
type: 'list',
name: 'instance_type',
message: function(answers) {
return setInstanceSizeQuestion(answers);
},
default: 'm3.medium',
choices: [
'm3.medium',
'm3.large',
'm3.xlarge',
'm3.2xlarge'
],
when: function(answers) {
return answers.familyChoice === 'M3';
}
}, {
type: 'list',
name: 'instance_type',
message: function(answers) {
return setInstanceSizeQuestion(answers);
},
default: 'm4.large',
choices: [
'm4.large',
'm4.xlarge',
'm4.2xlarge',
'm4.4xlarge',
'm4.10xlarge'
],
when: function(answers) {
return answers.familyChoice === 'M4';
}
}, {
type: 'list',
name: 'instance_type',
message: function(answers) {
return setInstanceSizeQuestion(answers);
},
default: 'c3.large',
choices: [
'c3.large',
'c3.xlarge',
'c3.2xlarge',
'c3.4xlarge',
'c3.8xlarge'
],
when: function(answers) {
return answers.familyChoice === 'C3';
}
}, {
type: 'list',
name: 'instance_type',
message: function(answers) {
return setInstanceSizeQuestion(answers);
},
default: 'c4.large',
choices: [
'c4.large',
'c4.xlarge',
'c4.2xlarge',
'c4.4xlarge',
'c4.8xlarge'
],
when: function(answers) {
return answers.familyChoice === 'C4';
}
}, {
type: 'list',
name: 'instance_type',
message: function(answers) {
return setInstanceSizeQuestion(answers);
},
default: 'r3.large',
choices: [
'r3.large',
'r3.xlarge',
'r3.2xlarge',
'r3.4xlarge',
'r3.8xlarge'
],
when: function(answers) {
return answers.familyChoice === 'R3';
}
}, {
type: 'list',
name: 'instance_type',
message: function(answers) {
return setInstanceSizeQuestion(answers);
},
default: 'g2.2xlarge',
choices: [
'g2.2xlarge',
'g2.8xlarge'
],
when: function(answers) {
return answers.familyChoice === 'G2';
}
}, {
type: 'list',
name: 'instance_type',
message: function(answers) {
return setInstanceSizeQuestion(answers);
},
default: 'i2.xlarge',
choices: [
'i2.xlarge',
'i2.2xlarge',
'i2.4xlarge',
'i2.8xlarge'
],
when: function(answers) {
return answers.familyChoice === 'I2';
}
}, {
type: 'list',
name: 'instance_type',
message: function(answers) {
return setInstanceSizeQuestion(answers);
},
default: 'd2.xlarge',
choices: [
'd2.xlarge',
'd2.2xlarge',
'd2.4xlarge',
'd2.8xlarge'
],
when: function(answers) {
return answers.familyChoice === 'D2';
}
}, {
type: 'input',
name: 'environment',
message: 'What is your environment instance tag?',
default: function(answers) {
return answers.appName;
}
}, {
type: 'input',
name: 'security_group',
message: 'What is the name of your security group?',
default: function(answers) {
return prependTagDefaultValue(answers, 'sg_');
}
}, {
type: 'input',
name: 'group',
message: 'What is your app\'s group name?\n' +
' (Note: Don\'t confuse this with your security group name.)\n ',
default: function(answers) {
return answers.appName;
}
}, {
type: 'input',
name: 'load_balancer',
message: 'What is the name of your load balancer',
default: function(answers) {
return prependTagDefaultValue(answers, 'lb-');
}
}, {
type: 'input',
name: 'remote_user',
message: 'Which operating system level user will ' +
'Ansible use to install and configure your application?',
default: function(answers) {
// TODO should be a choice. Or, better still, we should be able to select the AMI and that should pre-populate
// the user
return 'ubuntu';
}
}, {
type: 'input',
name: 'keypair',
message: 'What name does AWS use to refer to your keypair?',
default: function(answers) {
if (!answers.keypair) { return 'ansible'; }
return answers.appName;
}
}, {
type: 'input',
name: 'appPem',
message: 'What is the name of your .pem private key?',
validate: function(value) {
var regex = regexes.pem; // The key must end with .pem
var errorMessage = 'Your private key must end in \'.pem\'';
return validateInput(value, regex, errorMessage);
},
default: function(answers) {
return appendTagDefaultValue(answers, '.pem');
}
}, {
type: 'input',
name: 'ami_id',
message: 'What AMI ID would you like to use? (E.g., ami-47a23a30)',
validate: function(value) {
var regex = regexes.ami;
var errorMessage = 'The AMI ID must begin with \"ami-\" and must end' +
' with exactly eight lowercase, alphanumeric characters.';
return validateInput(value, regex, errorMessage);
},
default: "ami-fce3c696"
},
{
type: 'list',
name: 'using_vpc',
message: 'are you using EC2 classic or VPC-based EC2?',
choices: [
{
name: "VPC-based EC2",
value: true
},
{
name: "EC2 classic",
value: false
}
]
},
{
type: 'input',
name: 'vpc_subnet_id',
message: 'What VPC Subnet ID would you like to use? (E.g., subnet-6de3570a)',
validate: function(value){
var regex = regexes.vpc;
var errorMessage = 'The Subnet ID must begin with \"subnet-\" and must end with exactly eight lowercase, alphanumeric characters.';
return validateInput(value, regex, errorMessage);
},
when: function(hash){
return hash.using_vpc;
}
},
{
type: 'input',
name: 'aws_key',
message: 'What is your AWS Access Key (e.g. AKIAIOSFODNN7EXAMPLE)?',
validate: function(value) {
var regex = regexes.awsKey;
var errorMessage = 'AWS access key IDs must be 20 character, uppercase, ' +
'alphanumeric strings with nothing before or after.';
return validateInput(value, regex, errorMessage);
}
}, {
type: 'input',
name: 'aws_secret_key',
message: 'What is your AWS Secret Access Key (e.g. wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY)?',
validate: function(value) {
var regex = regexes.awsSecret;
// This regex is essentially the same as the above, but it looks for 40 character,
// base-64 strings instead.
var errorMessage = 'The AWS secret key must be a 40 character, ' +
'base-64 string with nothing before or after';
return validateInput(value, regex, errorMessage);
}
}];
module.exports = questions;
}());