-
-
Save TrentBartlem/292be37d496361d551fff6659d87fb0e to your computer and use it in GitHub Desktop.
Dynamodb autoscaling using a combination of CloudFormation and AWS SDK
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// snip: imports, applys etc. | |
// snip: assume 'deploy' task exists that deploys Serverless | |
task addScalingPolicy(dependsOn: deploy) { | |
description 'CloudFormation cannot do this yet, so we do it via SDK' | |
doLast { | |
final asClient = AWSApplicationAutoScalingClientBuilder.defaultClient() | |
final putScalingPolicy = { String tableName -> | |
final ttspReadConfig = new TargetTrackingScalingPolicyConfiguration( | |
predefinedMetricSpecification: new PredefinedMetricSpecification( | |
predefinedMetricType: 'DynamoDBReadCapacityUtilization'), | |
targetValue: 70.0) | |
final ttspWriteConfig = new TargetTrackingScalingPolicyConfiguration( | |
predefinedMetricSpecification: new PredefinedMetricSpecification( | |
predefinedMetricType: 'DynamoDBWriteCapacityUtilization'), | |
targetValue: 70.0) | |
final scalingPolicyRequest = new PutScalingPolicyRequest( | |
serviceNamespace: 'dynamodb', | |
resourceId: "table/$tableName", | |
scalableDimension: 'dynamodb:table:WriteCapacityUnits', | |
policyName: "table/${tableName}_WriteScalingPolicy", | |
policyType: 'TargetTrackingScaling', | |
targetTrackingScalingPolicyConfiguration: ttspWriteConfig) | |
asClient.putScalingPolicy(scalingPolicyRequest) | |
scalingPolicyRequest.with { | |
scalableDimension = 'dynamodb:table:ReadCapacityUnits' | |
policyName = "table/${tableName}_ReadScalingPolicy" | |
targetTrackingScalingPolicyConfiguration = ttspReadConfig | |
} | |
asClient.putScalingPolicy(scalingPolicyRequest) | |
} | |
putScalingPolicy 'myTable1' | |
putScalingPolicy 'myTable2' | |
// etc | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# snip: various serverless-related provider settings etc | |
resources: | |
Resources: # Essentially just CloudFormation | |
myTable1DynamoTable: | |
Type: AWS::DynamoDB::Table | |
Properties: | |
TableName: mytable1 | |
# insert AttributeDefinitions | |
# insert KeySchema | |
ProvisionedThroughput: | |
ReadCapacityUnits: ${env:MYTABLE1_READCAP} | |
WriteCapacityUnits: ${env:MYTABLE1_WRITECAP} | |
myTable2DynamoTable: | |
Type: AWS::DynamoDB::Table | |
Properties: | |
TableName: mytable2 | |
# insert AttributeDefinitions | |
# insert KeySchema | |
ProvisionedThroughput: | |
ReadCapacityUnits: ${env:MYTABLE2_READCAP} | |
WriteCapacityUnits: ${env:MYTABLE2_WRITECAP} | |
myAutoscalingRole: | |
Type: AWS::IAM::Role | |
Properties: | |
RoleName: DynamoDBAutoscaleRole | |
AssumeRolePolicyDocument: | |
Version: "2012-10-17" | |
Statement: | |
- | |
Effect: Allow | |
Principal: | |
Service: "application-autoscaling.amazonaws.com" | |
Action: "sts:AssumeRole" | |
Policies: | |
- PolicyName: "myAutoscalingPolicy" | |
PolicyDocument: | |
Version: "2012-10-17" | |
Statement: | |
- Effect: Allow | |
Action: | |
- dynamodb:DescribeTable | |
- dynamodb:UpdateTable | |
- cloudwatch:PutMetricAlarm | |
- cloudwatch:DescribeAlarms | |
- cloudwatch:DeleteAlarms | |
- cloudwatch:GetMetricStatistics | |
- cloudwatch:SetAlarmState | |
Resource: "*" | |
myTable1ReadTarget: | |
Type: AWS::ApplicationAutoScaling::ScalableTarget | |
DependsOn: myAutoscalingRole | |
Properties: | |
MaxCapacity: 10000 | |
MinCapacity: ${env:MYTABLE1_READCAP} | |
ResourceId: table/mytable1 | |
RoleARN: {Fn::GetAtt: [myAutoscalingRole, Arn]} | |
ScalableDimension: dynamodb:table:ReadCapacityUnits | |
ServiceNamespace: dynamodb | |
myTable1WriteTarget: | |
Type: AWS::ApplicationAutoScaling::ScalableTarget | |
DependsOn: myAutoscalingRole | |
Properties: | |
MaxCapacity: 10000 | |
MinCapacity: ${env:MYTABLE1_WRITECAP} | |
ResourceId: table/mytable1 | |
RoleARN: {Fn::GetAtt: [myAutoscalingRole, Arn]} | |
ScalableDimension: dynamodb:table:WriteCapacityUnits | |
ServiceNamespace: dynamodb | |
myTable2ReadTarget: | |
Type: AWS::ApplicationAutoScaling::ScalableTarget | |
DependsOn: myAutoscalingRole | |
Properties: | |
MaxCapacity: 10000 | |
MinCapacity: ${env:MYTABLE2_READCAP} | |
ResourceId: table/mytable2 | |
RoleARN: {Fn::GetAtt: [myAutoscalingRole, Arn]} | |
ScalableDimension: dynamodb:table:ReadCapacityUnits | |
ServiceNamespace: dynamodb | |
myTable2WriteTarget: | |
Type: AWS::ApplicationAutoScaling::ScalableTarget | |
DependsOn: myAutoscalingRole | |
Properties: | |
MaxCapacity: 10000 | |
MinCapacity: ${env:MYTABLE2_WRITECAP} | |
ResourceId: table/mytable2 | |
RoleARN: {Fn::GetAtt: [myAutoscalingRole, Arn]} | |
ScalableDimension: dynamodb:table:WriteCapacityUnits | |
ServiceNamespace: dynamodb |
Thanks for the example configurations! If you use serverless to create your CloudFormation Stack, have a look at my serverless-dynamodb-autoscaling plugin to configure Auto Scaling in your serverless.yml
with a clean configuration:
custom:
capacities:
- name: custom-table # DynamoDB table name
read:
minimum: 5 # Minimum read capacity
maximum: 1000 # Maximum read capacity
usage: 0.75 # Targeted usage percentage
write:
minimum: 40 # Minimum write capacity
maximum: 200 # Maximum write capacity
usage: 0.5 # Targeted usage percentage
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is an excellent gist on a little-documented CloudFormation feature. Note, in order to get the dynamodb scaling working all I needed were the correct CF resources shown here, and not the gradle SDK code.