Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 80 additions & 4 deletions src/provision.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Parameters:
- prod
Description: The Name Of Your Environment
<% extraParameters.forEach(function(param, index) {%>
<%= param.name %>
<%= param.name %>:
Type: <%= param.type %>
<% }); %>Resources:
<% tables.forEach(function(table, index) { %><%= table %>Table:
Expand Down Expand Up @@ -97,9 +97,9 @@ Parameters:
- "dynamodb:PutItem"
- "dynamodb:Query"
- "dynamodb:Scan"
- "dynamodb:UpdateItem"<% tables.forEach(function(table) { %>
Resource: !Sub arn:aws:dynamodb:$\{AWS::Region}:$\{AWS::AccountId}:table/$\{<%= table %>Table}
Resource: !Sub arn:aws:dynamodb:$\{AWS::Region}:$\{AWS::AccountId}:table/$\{<%= table %>Table}/index/*<% }); %>
- "dynamodb:UpdateItem"
Resource: <% tables.forEach(function(table) { %>
- !Sub arn:aws:dynamodb:$\{AWS::Region}:$\{AWS::AccountId}:table/$\{<%= table %>Table}*<% }); %>
- PolicyName: lambda-execute
PolicyDocument:
Version: "2012-10-17"
Expand All @@ -115,6 +115,82 @@ Parameters:
- "s3:PutObject"
Resource:
- "arn:aws:s3:::*"
DBAutoScaleRole:
DependsOn:<% tables.forEach(function(table) { %>
- <%= table %>Table<% }); %>
Type: AWS::IAM::Role
Properties:
Path: "/"
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service: application-autoscaling.amazonaws.com
Action: sts:AssumeRole
Policies:
- PolicyName: DynamoAutoscale
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- dynamodb:DescribeTable
- dynamodb:UpdateTable
Resource: "*"
- Effect: Allow
Action:
- cloudwatch:PutMetricAlarm
- cloudwatch:DescribeAlarms
- cloudwatch:DeleteAlarms
Resource: "*"
<% tables.forEach(function(table, index) { %><%= table %>DatabaseReadTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MaxCapacity: 1500
MinCapacity: 5
ResourceId:
Fn::Join:
- /
- - table
- !Ref <%= table %>Table
RoleARN: !GetAtt DBAutoScaleRole.Arn
ScalableDimension: dynamodb:table:ReadCapacityUnits
ServiceNamespace: dynamodb
<%= table %>DatabaseWriteTarget:
Type: AWS::ApplicationAutoScaling::ScalableTarget
Properties:
MaxCapacity: 1500
MinCapacity: 5
ResourceId: !GetAtt <%= table %>Table.Arn
RoleARN: !GetAtt DBAutoScaleRole.Arn
ScalableDimension: dynamodb:table:WriteCapacityUnits
ServiceNamespace: dynamodb
<%= table %>DatabaseAutoscaleReadPolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: !Sub $\{Environment}-<%= project %>-<%= table %>-AutoscalingReadPolicy
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref <%= table %>DatabaseReadTarget
TargetTrackingScalingPolicyConfiguration:
PredefinedMetricSpecification:
PredefinedMetricType: DynamoDBReadCapacityUtilization
ScaleOutCooldown: 60
ScaleInCooldown: 60
TargetValue: 80
<%= table %>DatabaseAutoscaleWritePolicy:
Type: AWS::ApplicationAutoScaling::ScalingPolicy
Properties:
PolicyName: !Sub $\{Environment}-<%= project %>-<%= table %>-AutoscalingWritePolicy
PolicyType: TargetTrackingScaling
ScalingTargetId: !Ref <%= table %>DatabaseWriteTarget
TargetTrackingScalingPolicyConfiguration:
PredefinedMetricSpecification:
PredefinedMetricType: DynamoDBWriteCapacityUtilization
ScaleOutCooldown: 60
ScaleInCooldown: 60
TargetValue: 80
<% }); %>
Outputs:<% tables.forEach(function(table) { %>
<%= table %>TableName:
Description: name of the <%= table %> table
Expand Down
54 changes: 47 additions & 7 deletions src/provision.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const provision = require('./provision')
const provision = require('./provision')
const expect = require('chai').expect

const AWS = require('aws-sdk')
const cloudformation = new AWS.CloudFormation()

//--------------------------------------------------
// Tests that the basic API contract is maintained.
Expand All @@ -11,7 +12,7 @@ const functions = [


functions.forEach(function(func_name) {
describe('provision module api', function() {
describe('provision module api', function() {
describe('"'+func_name+'"', function() {
it('should export a function', function() {
expect(provision[func_name]).to.be.a('function');
Expand All @@ -24,12 +25,51 @@ functions.forEach(function(func_name) {
//--------------------------------------------------
// Tests the generateCFN generates what we expect.
//--------------------------------------------------
describe('generateCFN module functionality', function() {
describe('generateCFN module functionality', function() {
describe('"generateCFN"', function() {
it('return a YML formatted cloudformation template with two tables defined and one IAM role', function() {
var cfn = provision.generateCFN("unit-tests", ["one", "hat"]);
it('return a YML formatted cloudformation template with two tables defined and one IAM role', function(done) {
this.timeout(15000)
const extraParams = [
{name: "Unit", type: "String"},
{name: "Product", type: "String"},
{name: "Subproduct", type: "String"},
{name: "Version", type: "String"},
]
var cfn = provision.generateCFN("UnitTests", ["one", "hat"], extraParams);
// console.log(cfn);
cloudformation.validateTemplate({
TemplateBody: cfn
}, function(err, data) {
expect(err).to.be.null;
// cloudformation.createStack({
// StackName: "int-test-dynamodb-graphql",
// OnFailure: "DELETE",
// TemplateBody: cfn,
// Parameters: [{
// ParameterKey: 'Unit',
// ParameterValue: "test",
// UsePreviousValue: false
// },{
// ParameterKey: 'Product',
// ParameterValue: "test",
// UsePreviousValue: false
// },{
// ParameterKey: 'Subproduct',
// ParameterValue: "test",
// UsePreviousValue: false
// },{
// ParameterKey: 'Version',
// ParameterValue: "test",
// UsePreviousValue: false
// }],
// Capabilities: ["CAPABILITY_NAMED_IAM"]
// }, function(err, data) {
// console.log(err, data)
// done()
// })

})

});
});
});