Skip to content

Instantly share code, notes, and snippets.

@abdennour
Last active December 20, 2017 17:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abdennour/5a975f33486171c866386f5299703c61 to your computer and use it in GitHub Desktop.
Save abdennour/5a975f33486171c866386f5299703c61 to your computer and use it in GitHub Desktop.
Calculator of DynamoDB reserved capacity via CloudFormation
# Should be deployed first as it exports "LambdaRoleExecutionARN" which is used by other stacks.
Resources:
LambdaRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: "sts:AssumeRole"
Policies:
-
PolicyName: LambdaLogToCloudWatch
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: Allow
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "arn:aws:logs:*:*:*"
Outputs:
LambdaRoleExecution:
Value: !GetAtt LambdaRole.Arn
Description: Common role used by Lambda with the minimum actions
Export:
Name: LambdaRoleExecutionARN
# DependsOn 0007-common-lambda-exec-role.yaml
# Caculation of dynamodB reserved capacity leveraging Custom resources (lambda)
Parameters:
ItemsCountPerSecondRead:
Type: Number
Description: Nbe of items to read per second
IsStronglyRead:
Type: String
AllowedValues: [true, false]
Default: true
Description: Strongly Read ?
ItemSizeRead:
Type: Number
Description: Item Size in Read (Kb)
ItemsCountPerSecondWrite:
Type: Number
Description: Nbe of items to write per second
ItemSizeWrite:
Type: Number
Description: Item Size in Write (Kb)
Resources:
GetReservedCapacityFunction:
Type: AWS::Lambda::Function
Properties:
Role: !ImportValue LambdaRoleExecutionARN
Handler: "index.handler"
Runtime: "nodejs6.10"
Timeout: 120
Code:
ZipFile: |
const response = require('cfn-response');
function getReadCapacity({itemsCount, itemsRequiredTimeRead, itemSize}, isStrongRead) {
const READ_UNIT = 4 ;//kb
const itemsPerSecond = itemsCount/itemsRequiredTimeRead;
const itemReadUnits = Math.ceil(itemSize / READ_UNIT)
const readThroughput = itemReadUnits * itemsPerSecond;
return Math.ceil(isStrongRead ? readThroughput : (readThroughput/2));
}
function getWriteCapacity({itemsCount, itemsRequiredTimeWrite, itemSize}) {
const WRITE_UNIT= 1; //kb
const itemsPerSecond = itemsCount/ itemsRequiredTimeWrite;
const itemWriteUnits = Math.ceil(itemSize/ WRITE_UNIT);
return Math.ceil(itemWriteUnits * itemsPerSecond);
}
exports.handler = function(event, context) {
if (event.RequestType === 'Delete') {
return response.send(event, context, response.SUCCESS);
}
if (event.RequestType === 'Create' || event.RequestType === 'Update') {
const readCapacity = getReadCapacity({
itemsCount: parseFloat(event.ResourceProperties.itemsCountPerSecondRead),
itemsRequiredTimeRead: 1,
itemSize: parseFloat(event.ResourceProperties.itemSizeRead)
}, event.ResourceProperties.isStronglyRead === 'true');
const writeCapacity= getWriteCapacity({
itemsCount: parseFloat(event.ResourceProperties.itemsCountPerSecondWrite),
itemsRequiredTimeWrite: 1,
itemSize: parseFloat(event.ResourceProperties.itemSizeWrite)
});
return response.send(event, context, response.SUCCESS, {
readCapacity,
writeCapacity
});
}
}
GetReservedCapacity:
Type: Custom::GetReservedCapacity
Properties:
ServiceToken: !GetAtt GetReservedCapacityFunction.Arn
itemsCountPerSecondRead: !Ref ItemsCountPerSecondRead
itemSizeRead: !Ref ItemSizeRead
isStronglyRead: !Ref IsStronglyRead
itemsCountPerSecondWrite: !Ref ItemsCountPerSecondWrite
itemSizeWrite: !Ref ItemSizeWrite
Outputs:
ReadCapacity:
Value: !GetAtt GetReservedCapacity.readCapacity
WriteCapacity:
Value: !GetAtt GetReservedCapacity.writeCapacity
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment