Skip to content

AWS::Serverless::SimpleTable Auto-Scaling #377

@oharaandrew314

Description

@oharaandrew314

DynamoDB Auto-Scaling via CFN is verbose to say the least. I propose that we add configuration properties to AWS::Serverless::SimpleTable which will implicitly generate all the necessary resources via the SAM translator.

SAM Template:

MyTable:
  Type: AWS::Serverless::SimpleTable
  Properties:
    ...
    AutoScaling: (optional)
      ReadScaling: (optional, disabled if omitted)
        MinCapacity: Integer (default: 5, same as console)
        MaxCapacity: Integer (default: 4000, same as console)
        TargetUtilization: Integer (default: 70, same as console)
      WriteScaling: (optional, disabled if omitted)
        MinCapacity: Integer (default: 5, same as console)
        MaxCapacity: Integer (default: 4000, same as console)
        TargetUtilization: Integer (default: 70, same as console)

Translated CFN Template:

MyTable:
  Type: AWS::DynamoDB::Table
  Properties:
    ...

MyTableScalingRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: "2012-10-17"
      Statement:
      - Effect: Allow
        Principal:
          Service:
          - application-autoscaling.amazonaws.com
        Action:
        - sts:AssumeRole
    Path: "/"
    Policies:
    - PolicyName: root
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
        - Effect: "Allow"
          Action:
          - dynamodb:DescribeTable
          - dynamodb:UpdateTable
          - cloudwatch:PutMetricAlarm
          - cloudwatch:DescribeAlarms
          - cloudwatch:GetMetricStatistics
          - cloudwatch:SetAlarmState
          - cloudwatch:DeleteAlarms
          Resource: !GetAtt MyTable.Arn

MyTableWriteCapacityScalableTarget:
  Type: AWS::ApplicationAutoScaling::ScalableTarget
  Properties:
    MaxCapacity: Integer (provided by SAM template)
    MinCapacity: Integer (provided by SAM template)
    ResourceId: !Sub table/${MyTableScalingRole.Arn}
    ScalableDimension: dynamodb:table:WriteCapacityUnits
    ServiceNamespace: dynamodb

MyTableWriteScalingPolicy:
  Type: AWS::ApplicationAutoScaling::ScalingPolicy
  Properties:
    PolicyName: MyTableWriteAutoScalingPolicy
    PolicyType: TargetTrackingScaling
    ScalingTargetId: !Ref MyTableWriteCapacityScalableTarget
    TargetTrackingScalingPolicyConfiguration:
      TargetValue: Integer  (provided by SAM template)
      ScaleInCooldown: 60
      ScaleOutCooldown: 60
      PredefinedMetricSpecification:
        PredefinedMetricType: DynamoDBWriteCapacityUtilization

MyTableReadCapacityScalableTarget:
  Type: AWS::ApplicationAutoScaling::ScalableTarget
  Properties:
    MaxCapacity: Integer (provided by SAM template)
    MinCapacity: Integer (provided by SAM template)
    ResourceId: !Sub table/${MyTableScalingRole.Arn}
    ScalableDimension: dynamodb:table:ReadCapacityUnits
    ServiceNamespace: dynamodb

MyTableReadScalingPolicy:
  Type: AWS::ApplicationAutoScaling::ScalingPolicy
  Properties:
    PolicyName: MyTableReadAutoScalingPolicy
    PolicyType: TargetTrackingScaling
    ScalingTargetId: !Ref MyTableReadCapacityScalableTarget
    TargetTrackingScalingPolicyConfiguration:
      TargetValue: Integer (provided by SAM template)
      ScaleInCooldown: 60
      ScaleOutCooldown: 60
      PredefinedMetricSpecification:
        PredefinedMetricType: DynamoDBReadCapacityUtilization

I welcome any discussion on this proposal. This proposed implementation would generate a scaling role per table, which would be wasteful. The console creates and reuses a single role for this purpose, but this may be awkward to implement in SAM.

I would be willing to work on this once I become more familiar with the internals of the SAM translator, but it may best be left to someone with more intimate knowledge.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions