Use the Conformity Knowledge Base AI to help improve your Cloud Posture

Enable Auto Scaling

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: Medium (should be achieved)

Ensure that Amazon DynamoDB Auto Scaling feature is enabled to dynamically adjust provisioned throughput (read and write) capacity for your tables and global secondary indexes. DynamoDB Auto Scaling makes use of Application Auto Scaling service which implements a target tracking algorithm to adjust the provisioned throughput of the DynamoDB tables/indexes upward or downward in response to actual workload. Once DynamoDB Auto Scaling is enabled, all you have to do is to define the desired target utilization and to provide upper and lower bounds for read and write capacity. Then, the feature will monitor throughput consumption using Amazon CloudWatch and will adjust provisioned capacity up or down as needed.

Performance
efficiency
Cost
optimisation
Reliability
Operational
excellence

Once enabled, DynamoDB Auto Scaling will start monitoring your tables and indexes in order to automatically adjust throughput in response to changes in application workload. This can make it easier to administer your DynamoDB data, help you maximize your application availability and help you reduce your DynamoDB costs.


Audit

To determine if Auto Scaling is enabled for your Amazon DynamoDB tables and indexes, perform the following operations:

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon DynamoDB console at https://console.aws.amazon.com/dynamodbv2/.

03 In the main navigation panel, under DynamoDB, choose Tables.

04 Click on the name (link) of the Amazon DynamoDB table that you want to examine.

05 Select the Additional settings tab to access the additional settings configured for the selected table.

06 In the Table capacity section, check the Read capacity auto scaling and Write capacity auto scaling attributes values. If both attributes are set to Off, DynamoDB Auto Scaling is not enabled for the selected Amazon DynamoDB table.

07 Choose Index capacity and check the Read capacity and Write capacity columns for each defined index. If both Read capacity and Write capacity values are set to Auto scaling is off, the Auto Scaling feature is not enabled for the verified global secondary index.

08 Repeat steps no. 4 – 7 for each Amazon DynamoDB table (and the associated indexes) available within the current AWS region.

09 Change the AWS cloud region from the navigation bar and repeat the Audit process for other regions.

Using AWS CLI

01 Run list-tables command (OSX/Linux/UNIX) with custom query filters to list the name of each Amazon DynamoDB table created in the selected AWS region:

aws dynamodb list-tables
  --region us-east-1
  --output table
  --query 'TableNames'

02 The command output should return a table with the requested table names:

--------------------------
|       ListTables       |
+------------------------+
|  cc-product-reviews    |
|  cc-product-inventory  |
+------------------------+ 

03 Run describe-table command (OSX/Linux/UNIX) with custom query filters to list all the global secondary indexes created for the selected Amazon DynamoDB table:

aws dynamodb describe-table
  --region us-east-1
  --table-name cc-product-reviews
  --output table
  --query 'Table.GlobalSecondaryIndexes[*].IndexName'

04 The command output should return the requested index names:

---------------------------
|      DescribeTable      |
+-------------------------+
|  ProductCategory-index  |
+-------------------------+

05 Run describe-scalable-targets command (OSX/Linux/UNIX) using the name of the Amazon DynamoDB table and the name of the global secondary index as the identifier parameters, to obtain information about the scalable targets registered for the selected DynamoDB table and its global secondary index. A scalable target represents a resource that Application Auto Scaling service can scale in or scale out:

aws application-autoscaling describe-scalable-targets
  --region us-east-1
  --service-namespace dynamodb
  --resource-ids "table/cc-product-inventory" "table/cc-product-inventory/ProductCategory-index"

06 The command output should return the information available for the registered scalable targets:

{
	"ScalableTargets": []
}

If the describe-scalable-targets command output returns an empty array as value for the "ScalableTargets" attribute, as shown in the output example above, the Auto Scaling feature is not enabled for the selected Amazon DynamoDB table and its global secondary index.

07 Repeat steps no. 3 – 6 for each Amazon DynamoDB table (and the associated indexes) available in the selected AWS region.

08 Change the AWS cloud region by updating the --regioncommand parameter value and repeat the Audit process for other regions.

Remediation / Resolution

To enable Auto Scaling for your Amazon DynamoDB tables and indexes, perform the following operations:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
	"AWSTemplateFormatVersion": "2010-09-09",
	"Description": "Enable Auto Scaling",
	"Resources": {
		"DynamoDbTable": {
			"Type": "AWS::DynamoDB::Table",
			"Properties": {
				"TableName": "cc-game-scores",
				"BillingMode": "PROVISIONED",
				"AttributeDefinitions": [
					{
						"AttributeName": "UserId",
						"AttributeType": "S"
					},
					{
						"AttributeName": "GameTitle",
						"AttributeType": "S"
					},
					{
						"AttributeName": "TopScore",
						"AttributeType": "N"
					}
				],
				"KeySchema": [
					{
						"AttributeName": "UserId",
						"KeyType": "HASH"
					},
					{
						"AttributeName": "GameTitle",
						"KeyType": "RANGE"
					}
				],
				"ProvisionedThroughput": {
					"ReadCapacityUnits": "5",
					"WriteCapacityUnits": "5"
				}
			}
		},
		"DynamoDbTableScalingRole": {
			"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": "dynamodb-custom-access",
						"PolicyDocument": {
							"Version": "2012-10-17",
							"Statement": [
								{
									"Effect": "Allow",
									"Action": [
										"dynamodb:DescribeTable",
										"dynamodb:UpdateTable",
										"cloudwatch:PutMetricAlarm",
										"cloudwatch:DescribeAlarms",
										"cloudwatch:GetMetricStatistics",
										"cloudwatch:SetAlarmState",
										"cloudwatch:DeleteAlarms"
									],
									"Resource": "*"
								}
							]
						}
					}
				]
			}
		},
		"DynamoDbAutoscalingTarget": {
			"Type": "AWS::ApplicationAutoScaling::ScalableTarget",
			"Properties": {
				"MaxCapacity": 1500,
				"MinCapacity": 150,
				"ResourceId": {
					"Fn::Join": [
						"/",
						[
							"table",
							{
								"Ref": "DynamoDbTable"
							}
						]
					]
				},
				"RoleARN": {
					"Fn::GetAtt": [
						"DynamoDbTableScalingRole",
						"Arn"
					]
				},
				"ScalableDimension": "dynamodb:table:ReadCapacityUnits",
				"ServiceNamespace": "dynamodb"
			}
		},
		"DynamoDbAutoscalingPolicy": {
			"Type": "AWS::ApplicationAutoScaling::ScalingPolicy",
			"Properties": {
				"PolicyName": "AwsDynamoDbScalingPolicy",
				"PolicyType": "TargetTrackingScaling",
				"ScalingTargetId": {
					"Ref": "DynamoDbAutoscalingTarget"
				},
				"TargetTrackingScalingPolicyConfiguration": {
					"TargetValue": 70.0,
					"ScaleInCooldown": 60,
					"ScaleOutCooldown": 60,
					"PredefinedMetricSpecification": {
						"PredefinedMetricType": "DynamoDBReadCapacityUtilization"
					}
				}
			}
		}
	}
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
	Description: Enable Auto Scaling
	Resources:
	DynamoDbTable:
		Type: AWS::DynamoDB::Table
		Properties:
		TableName: cc-game-scores
		BillingMode: PROVISIONED
		AttributeDefinitions:
			- AttributeName: UserId
			AttributeType: S
			- AttributeName: GameTitle
			AttributeType: S
			- AttributeName: TopScore
			AttributeType: N
		KeySchema:
			- AttributeName: UserId
			KeyType: HASH
			- AttributeName: GameTitle
			KeyType: RANGE
		ProvisionedThroughput:
			ReadCapacityUnits: '5'
			WriteCapacityUnits: '5'
	DynamoDbTableScalingRole:
		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: dynamodb-custom-access
			PolicyDocument:
				Version: '2012-10-17'
				Statement:
				- Effect: Allow
					Action:
					- dynamodb:DescribeTable
					- dynamodb:UpdateTable
					- cloudwatch:PutMetricAlarm
					- cloudwatch:DescribeAlarms
					- cloudwatch:GetMetricStatistics
					- cloudwatch:SetAlarmState
					- cloudwatch:DeleteAlarms
					Resource: '*'
	DynamoDbAutoscalingTarget:
		Type: AWS::ApplicationAutoScaling::ScalableTarget
		Properties:
		MaxCapacity: 1500
		MinCapacity: 150
		ResourceId: !Join
			- /
			- - table
			- !Ref 'DynamoDbTable'
		RoleARN: !GetAtt 'DynamoDbTableScalingRole.Arn'
		ScalableDimension: dynamodb:table:ReadCapacityUnits
		ServiceNamespace: dynamodb
	DynamoDbAutoscalingPolicy:
		Type: AWS::ApplicationAutoScaling::ScalingPolicy
		Properties:
		PolicyName: AwsDynamoDbScalingPolicy
		PolicyType: TargetTrackingScaling
		ScalingTargetId: !Ref 'DynamoDbAutoscalingTarget'
		TargetTrackingScalingPolicyConfiguration:
			TargetValue: 70.0
			ScaleInCooldown: 60
			ScaleOutCooldown: 60
			PredefinedMetricSpecification:
			PredefinedMetricType: DynamoDBReadCapacityUtilization

Using Terraform (AWS Provider)

01 Terraform configuration file (.tf):

terraform {
	required_providers {
		aws = {
			source  = "hashicorp/aws"
			version = "~> 4.0"
		}
	}

	required_version = ">= 0.14.9"
}

provider "aws" {
	profile = "default"
	region  = "us-east-1"
}

resource "aws_dynamodb_table" "dynamodb-table" {
	name           = "cc-game-scores"
	billing_mode   = "PROVISIONED"
	hash_key       = "UserId"
	range_key      = "GameTitle"
	read_capacity  = 5
	write_capacity = 5

	attribute {
		name = "UserId"
		type = "S"
	}

	attribute {
		name = "GameTitle"
		type = "S"
	}

	attribute {
		name = "TopScore"
		type = "N"
	}
}

resource "aws_appautoscaling_target" "dynamodb-autoscaling-target" {
	resource_id        = "table/${aws_dynamodb_table.dynamodb-table.name}"
	scalable_dimension = "dynamodb:table:ReadCapacityUnits"
	service_namespace  = "dynamodb"
	min_capacity       = 150
	max_capacity       = 1500
	role_arn           = "arn:aws:iam::123456789012:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable"
}

resource "aws_appautoscaling_policy" "dynamodb-autoscaling-policy" {
	name               = "DynamoDBReadCapacityUtilization:${aws_appautoscaling_target.dynamodb-autoscaling-target.resource_id}"
	service_namespace  = aws_appautoscaling_target.dynamodb-autoscaling-target.service_namespace
	scalable_dimension = aws_appautoscaling_target.dynamodb-autoscaling-target.scalable_dimension
	resource_id        = aws_appautoscaling_target.dynamodb-autoscaling-target.resource_id
	policy_type        = "TargetTrackingScaling"

	target_tracking_scaling_policy_configuration {
	   predefined_metric_specification {
		  predefined_metric_type = "DynamoDBReadCapacityUtilization"
	   }
	}

	target_value = 70
}

Using AWS Console

01 Sign in to the AWS Management Console.

02 Navigate to Amazon DynamoDB console at https://console.aws.amazon.com/dynamodbv2/.

03 In the main navigation panel, under DynamoDB, choose Tables.

04 Click on the name (link) of the Amazon DynamoDB table that you want to configure.

05 Select the Additional settings tab to access the additional settings configured for the selected table.

06 In the Read/write capacity section choose Edit to modify the resource capacity settings.

07 In the Capacity mode, select either On-demand to enable on-demand capacity mode or Provisioned to enable provisioned mode with auto scaling. If you select Provisioned, continue the Remediation process with the next step.

08 In the Table capacity section, perform the following actions:

  1. For Read capacity and Write capacity set the Auto scaling setting to On to enable DynamoDB Auto Scaling for the selected table.
  2. For Minimum capacity units, type your lower boundary for the auto-scaling range based on your application workload.
  3. For Maximum capacity units, type your upper boundary for the auto-scaling range.
  4. In Target utilization (%) box, type the target utilization for the table (percentage).
  5. Select Use the same write capacity settings for all global secondary indexes checkboxes for both Read capacity and Write capacity settings to enable Auto Scaling for the associated global secondary indexes. This option allows the Auto Scaling feature to uniformly scale all the global secondary indexes on the selected table. This includes existing global secondary indexes and any other indexes that you will create for the selected table in the future.
  6. Choose Save changes to apply the changes. By enabling DynamoDB Auto Scaling, you authorize Amazon DynamoDB to scale capacity by using the predefined service-linked role created for Auto Scaling, i.e. AWSServiceRoleForApplicationAutoScaling_DynamoDBTable.

09 Repeat steps no. 4 – 8 for each Amazon DynamoDB table that you want to configure, available within the current AWS region.

10 Change the AWS cloud region from the navigation bar and repeat the Remediation process for other AWS regions.

Using AWS CLI

01 Run update-table command (OSX/Linux/UNIX) with the --billing-mode parameter set to PAY_PER_REQUEST to enable on-demand capacity mode:

aws dynamodb update-table 
  --region us-east-1 
  --table-name cc-product-reviews 
  --billing-mode PAY_PER_REQUEST

02 The command output should return the information available for the modified DynamoDB table:

{
	"TableDescription": {
		"AttributeDefinitions": [
			{
				"AttributeName": "ProductCategory",
				"AttributeType": "S"
			}
		],
		"TableName": "cc-product-reviews",
		"KeySchema": [
			{
				"AttributeName": "music",
				"KeyType": "HASH"
			},
			{
				"AttributeName": "artist",
				"KeyType": "RANGE"
			}
		],
		"TableStatus": "UPDATING",
		"CreationDateTime": "2023-07-27T18:11:15.823000+00:00",
		"ProvisionedThroughput": {
			"LastDecreaseDateTime": "2023-07-27T18:54:21.954000+00:00",
			"NumberOfDecreasesToday": 0,
			"ReadCapacityUnits": 0,
			"WriteCapacityUnits": 0
		},
		"TableSizeBytes": 0,
		"ItemCount": 0,
		"TableArn": "arn:aws:dynamodb:us-east-1:123456789012:table/cc-product-reviews",
		"BillingModeSummary": {
			"BillingMode": "PAY_PER_REQUEST"
		},
		"GlobalSecondaryIndexes": [
			{
				"IndexName": "ProductCategory-index",
				"KeySchema": [
					{
						"AttributeName": "ProductCategory",
						"KeyType": "HASH"
					}
				],
				"Projection": {
					"ProjectionType": "ALL"
				},
				"IndexStatus": "UPDATING",
				"ProvisionedThroughput": {
					"NumberOfDecreasesToday": 0,
					"ReadCapacityUnits": 0,
					"WriteCapacityUnits": 0
				},
				"IndexSizeBytes": 0,
				"ItemCount": 0,
				"IndexArn": "arn:aws:dynamodb:us-east-1:123456789012:table/cc-product-reviews/index/ProductCategory-index"
			}
		],
		"TableClassSummary": {
			"TableClass": "STANDARD"
		}
	}
}

03 For provisioned mode with auto scaling, run register-scalable-target command (OSX/Linux/UNIX) to register a scalable target with the selected Amazon DynamoDB table. A scalable target is a resource that Application Auto Scaling can scale out or scale in. Use the predefined service-linked role created for DynamoDB Auto Scaling, i.e. AWSServiceRoleForApplicationAutoScaling_DynamoDBTable. The following configuration allows the auto-scaling service to dynamically adjust the provisioned read capacity for "cc-product-reviews" table within the range of 150 to 1500 units. To configure the provisioned write capacity for the selected table, set --scalable-dimension value to dynamodb:table:WriteCapacityUnits and run again the register-scalable-target command (the command does not produce an output):

aws application-autoscaling register-scalable-target
  --region us-east-1
  --service-namespace dynamodb
  --resource-id table/cc-product-reviews
  --scalable-dimension dynamodb:table:ReadCapacityUnits
  --min-capacity 150
  --max-capacity 1500
  --role-arn arn:aws:iam::123456789012:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable

04 Run register-scalable-target command (OSX/Linux/UNIX) to register a scalable target with the selected DynamoDB table index. The following Application Auto Scaling configuration allows the service to dynamically adjust the provisioned read capacity for "ProductCategory-index" global secondary index within the range of 150 to 1500 capacity units. To configure the provisioned write capacity for the selected index, set --scalable-dimension value to dynamodb:index:WriteCapacityUnits and run again the register-scalable-target command (the command does not return an output):

aws application-autoscaling register-scalable-target
  --region us-east-1
  --service-namespace dynamodb
  --resource-id table/cc-product-reviews/index/ProductCategory-index
  --scalable-dimension dynamodb:index:ReadCapacityUnits
  --min-capacity 150
  --max-capacity 1500
  --role-arn arn:aws:iam::123456789012:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable

05 Define the policy for the scalable targets created at the previous steps. To create the required scaling policy, paste the following information into a new policy document named auto-scaling-policy.json. Replace DynamoDBReadCapacityUtilization with DynamoDBWriteCapacityUtilization based on the scalable dimension used, i.e. DynamoDBReadCapacityUtilization for dynamodb:table:ReadCapacityUnits dimension and DynamoDBWriteCapacityUtilization for dynamodb:table:WriteCapacityUnits:

{
	"PredefinedMetricSpecification": {
		"PredefinedMetricType": "DynamoDBReadCapacityUtilization"
	},
	"ScaleOutCooldown": 60,
	"ScaleInCooldown": 60,
	"TargetValue": 70.0
}

06 Run put-scaling-policy command (OSX/Linux/UNIX) to attach the scaling policy defined at the previous step to the scalable targets registered with the selected Amazon DynamoDB table. The put-scaling-policy command request will also enable Application Auto Scaling to create two CloudWatch alarms: one for the upper and one for the lower boundary of the scaling target range. To set up the required policy for provisioned write capacity (table), set --scalable-dimension value to dynamodb:table:WriteCapacityUnits and run again the put-scaling-policy command:

aws application-autoscaling put-scaling-policy
  --region us-east-1
  --service-namespace dynamodb
  --resource-id table/cc-product-reviews
  --scalable-dimension dynamodb:table:ReadCapacityUnits
  --policy-name cc-autoscaling-policy
  --policy-type TargetTrackingScaling
  --target-tracking-scaling-policy-configuration file://auto-scaling-policy.json

07 The command output should return the command request information, including details regarding the newly created Amazon CloudWatch alarms:

{
	"Alarms": [
		{
			"AlarmName": "TargetTracking-table/cc-product-reviews-ProvisionedCapacityHigh-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee",
			"AlarmARN": "arn:aws:cloudwatch:us-east-1:123456789012:alarm:TargetTracking-table/cc-product-reviews-ProvisionedCapacityHigh-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee"
		},
		{
			"AlarmName": "TargetTracking-table/cc-product-reviews-ProvisionedCapacityLow-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee",
			"AlarmARN": "arn:aws:cloudwatch:us-east-1:123456789012:alarm:TargetTracking-table/cc-product-reviews-ProvisionedCapacityLow-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee"
		}
	],
	"PolicyARN": "arn:aws:autoscaling:us-east-1:123456789012:scalingPolicy:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee:resource/dynamodb/table/cc-product-reviews:policyName/cc-autoscaling-policy"
}

08 Run put-scaling-policy command (OSX/Linux/UNIX) to attach the scaling policy defined at step no. 3 to the scalable targets registered with the selected DynamoDB table index (i.e. the global secondary index). The put-scaling-policy command request will also enable Application Auto Scaling to create two CloudWatch alarms: one for the upper and one for the lower boundary of the scaling target range. To set up the required policy for provisioned write capacity (index), set --scalable-dimension value to dynamodb:index:WriteCapacityUnits and run again the put-scaling-policy command:

aws application-autoscaling put-scaling-policy
  --region us-east-1
  --service-namespace dynamodb
  --resource-id table/cc-product-reviews/index/ProductCategory-index
  --scalable-dimension dynamodb:index:ReadCapacityUnits
  --policy-name cc-autoscaling-policy
  --policy-type TargetTrackingScaling
  --target-tracking-scaling-policy-configuration file://auto-scaling-policy.json

09 The command output should return the request information, including details about the newly created CloudWatch alarms:

{
	"Alarms": [
		{
			"AlarmName": "TargetTracking-table/cc-product-reviews/index/ProductCategory-index-ProvisionedCapacityHigh-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee",
			"AlarmARN": "arn:aws:cloudwatch:us-east-1:123456789012:alarm:TargetTracking-table/cc-product-reviews/index/ProductCategory-index-ProvisionedCapacityHigh-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee"
		},
		{
			"AlarmName": "TargetTracking-table/cc-product-reviews/index/ProductCategory-index-ProvisionedCapacityLow-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee",
			"AlarmARN": "arn:aws:cloudwatch:us-east-1:123456789012:alarm:TargetTracking-table/cc-product-reviews/index/ProductCategory-index-ProvisionedCapacityLow-aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee"
		}
	],
	"PolicyARN": "arn:aws:autoscaling:us-east-1:123456789012:scalingPolicy:aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeee:resource/dynamodb/table/cc-product-reviews/index/ProductCategory-index:policyName/cc-autoscaling-policy"
}

10 Repeat steps no. 1 – 9 for each Amazon DynamoDB table that you want to configure, available in the selected AWS region.

11 Change the AWS cloud region by updating the --region command parameter value and repeat the Remediation process for other AWS regions.

References