Disabled autoscaling DynamoDB tables

Risk level: Medium

Rule ID: DDB-002

This rule checks whether auto-scaling is enabled for AWS DynamoDB tables in your cloud environment.

Auto-scaling is enabled by default for DynamoDB tables. With the help of AWS CloudWatch, it dynamically adjusts the throughput (read and write) capacity of your provisioned DB tables to meet traffic demands.

For performance and cost optimization, nOps recommends you consider enabling Autoscaling on the DB tables.

This rule can help you work with the following:

  • AWS Well-Architected Framework.
  • SOC 2 Readiness Report

Audit

 

Using AWS Console

1. Sign in and access the DynamoDB dashboard at https://console.aws.amazon.com/dynamodb/.
 
2. Under the Dashboard section by the left, click on the Tables option.
 
3. Please select and copy the name of the desired DynamoDB table that you wish to examine its capacity mode. For example, we will examine a table named terraform-state in our AWS account.
 
4. Select the top Actions drop-down menu and choose the Edit Capacity option as shown below.


 
5. Scroll down to Table Capacity to verify if the Autoscaling feature is on or off for Read Capacity and Write Capacity.

If the Off radio button is selected, the Autoscaling feature for this table is disabled.
 
6. Repeat steps 3 – 5 to check if DynamoDB Auto Scaling is enabled for other tables in the current region.
 
7. Switch the AWS region and perform the entire audit procedure for the remaining regions you have provisioned DB resources in.

Using AWS CLI

1. Run the list-tables command to retrieve an array of all DynamoDB tables provisioned in the specified region. Below is a sample output:

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

**Output**
[
		...
    "terrafom-lock",
    "terraform-lock",
    "terraform-state",
    "terraform-state-rp",
		...
]

 
2. Choose a desired table name from the output list and execute the describe-scalable-targets command using the desired table name to retrieve its details.


**Query**
aws application-autoscaling describe-scalable-targets \\
		--region us-east-1 \\
    --service-namespace dynamodb \\
    --resource-id "terraform-state"

**Output**
{
    "ScalableTargets": []
}

If the command returns an empty output, as seen above, it indicates that the specified table's Auto Scaling status is disabled.
 
3. Execute step 2 for the rest of the AWS DynamoDB tables provisioned in the current region.
 
4. To ascertain the Auto-scaling status of provisioned DB tables in other regions, update the AWS region by changing the --region value and repeat the entire audit procedure for the tables provisioned in such region.

Remediation / Resolution

Using AWS Console

1. Access the DynamoDB dashboard at https://console.aws.amazon.com/dynamodb/.
 
2. Under the Dashboard section by the left, select the Tables option. Under the Dashboard section by the left, select the Tables option.
 
3. Select the DynamoDB table you want to reconfigure (see Audit section part I to identify the right resource).
 
4. Select the top Actions drop-down menu and choose the Edit Capacity option as shown below.


 
5. Scroll down to the Table Capacity section and perform the following:

a. Select On for Autoscaling feature for both Read and Write Capacity sub-sections.

b. Set Minimum Capacity Units to the desired value, e.g., 1.

c. Set Maximum Capacity Units to the desired value, e.g., 10.

d. Set Target Utilization e.g 70%

e.Save Changes


 
6. Repeat steps 3 - 4 to enable auto-scaling for the rest of the AWS DynamoDB tables provisioned in the current region.
 
7. Switch the AWS region at the top navigation bar and repeat the entire audit procedure for the remaining regions you have provisioned DB resources in.

Using AWS CLI

1. To configure auto-scaling on a DynamoDB table, first, create an IAM Service Role for Application AutoScaling to adjust your current DynamoDB table's provisioned throughput specifications. To do this:

a. Establish an access-defining trust relationship for the Service Role: To build the role's trust relationship policy that will specify the necessary access-control conditions, copy and paste the content below into a new policy document file called autoscale-service-role-trust-policy.json

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "application-autoscaling.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

 
b. Generate the required service role by executing the create-role command as shown below. Remember also to use the trust policy we specified earlier:

aws iam create-role \\
	--role-name dynamodb-autoscale-role \\
	--assume-role-policy-document file://autoscale-service-role-trust-policy.json

**Output**
{
    "Role": {
        "Path": "/",
        "RoleName": "dynamodb-autoscale-role",
        "RoleId": "AROA2DYVJGKZ33KXR45IP",
        "Arn": "arn:aws:iam::695292474035:role/dynamodb-autoscale-role",
        "CreateDate": "2021-11-05T23:34:47+00:00",
        "AssumeRolePolicyDocument": {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Effect": "Allow",
                    "Principal": {
                        "Service": "application-autoscaling.amazonaws.com"
                    },
                    "Action": "sts:AssumeRole"
                }
            ]
        }
    }
}

 
c. Add the necessary permissions to the IAM Role :

I. Copy and paste the details below into a new JSON document titled autoscale-service-role-access-policy.json. This will generate the policy required to grant permissions to describe DynamoDB tables and alter CloudWatch alarms for Autoscaling triggers to act.

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:DescribeTable",
                "dynamodb:UpdateTable",
                "cloudwatch:PutMetricAlarm",
                "cloudwatch:DescribeAlarms",
                "cloudwatch:GetMetricStatistics",
                "cloudwatch:SetAlarmState",
                "cloudwatch:DeleteAlarms"
            ],
            "Resource": "*"
        }
    ]
}

 
II. Next, generate the IAM service role policy by executing the create-policy command as shown below. Again, remember to use the IAM service role outlined earlier, i.e., autoscale-service-role-access-policy.json:

aws iam create-policy \\
	--region us-east-1 \\
	--policy-name dynamodb-autoscale-policy \\
	--policy-document file://autoscale-service-role-access-policy.json

**Output**
{
    "Policy": {
        "PolicyName": "dynamodb-autoscale-policy",
        "PolicyId": "ANPA2DYVJGKZZM6YRLONZ",
        "Arn": "arn:aws:iam::695292474035:policy/dynamodb-autoscale-policy",
        "Path": "/",
        "DefaultVersionId": "v1",
        "AttachmentCount": 0,
        "PermissionsBoundaryUsageCount": 0,
        "IsAttachable": true,
        "CreateDate": "2021-11-05T23:38:42+00:00",
        "UpdateDate": "2021-11-05T23:38:42+00:00"
    }
}

 
III. Attach Policy to the IAM Role: Attach the generated access policy with the newly formed IAM Service Role by executing the IAM attach-role-policy command as shown below. Please note that you must use Policy ARN**.**

aws iam attach-role-policy \\
	--region us-east-1 \\
	--role-name dynamodb-autoscale-role \\
	--policy-arn arn:aws:iam::695292474035:policy/dynamodb-autoscale-policy

**Output**
None

 
2. After completing Step 1, it's time to configure a scalable target, a resource that may be scaled via Application Auto Scaling. This is done by executing the register-scalable-target command along with the specified DynamoDB Table's name.

The Application Auto Scaling setup outlined below enables AWS DynamoDB to dynamically alter the allocated read/write capacity for the "terraform-state" table between 1 and 10 units.

**Query 1 - ReadCapacity Autoscaling**
aws application-autoscaling register-scalable-target \\
	--region us-east-1 \\
	--service-namespace dynamodb \\
	--resource-id "table/terraform-stat" \\
	--scalable-dimension dynamodb:table:ReadCapacityUnits \\
	--min-capacity 1 \\
	--max-capacity 10 \\
	--role-arn arn:aws:iam::695292474035:role/dynamodb-autoscale-role

**Output**
None

**Query 2 - WriteCapacity Autoscaling**
aws application-autoscaling register-scalable-target \\
	--region us-east-1 \\
	--service-namespace dynamodb \\
	--resource-id "table/terraform-state" \\
	--scalable-dimension dynamodb:table:WriteCapacityUnits \\
	--min-capacity 1 \\
	--max-capacity 10 \\
	--role-arn arn:aws:iam::695292474035:role/dynamodb-autoscale-role

**Output**
None

 
3. Specify the scalable targets' scaling policy.

a. To generate the desired read scaling policy, copy and paste the content below into a new policy document titled autoscaling-read-policy.json.

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

 
b. To generate the desired write scaling policy, copy and paste the content below into a new policy document titled autoscaling-write-policy.json.

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

 
4. Using the samples below, execute the auto-scaling put-scaling-policy command to apply previously defined scaling policies to the scalable targets associated with the specified DynamoDB table.

a. Read Scaling Policy

aws application-autoscaling put-scaling-policy \\
	--region us-east-1 \\
	--service-namespace dynamodb \\
	--resource-id table/terraform-state \\
	--scalable-dimension dynamodb:table:ReadCapacityUnits \\
	--policy-name read-autoscaling-policy \\
	--policy-type TargetTrackingScaling \\
	--target-tracking-scaling-policy-configuration file://autoscaling-read-policy.json

**Output**
{
    "PolicyARN": "arn:aws:autoscaling:us-east-1:695292474035:scalingPolicy:e50014ec-2183-45e4-a617-4be344070d81:resource/dynamodb/table/terraform-state:policyName/read-autoscaling-policy",
    "Alarms": [
        {
            "AlarmName": "TargetTracking-table/terraform-state-AlarmHigh-b050c201-cf7d-4856-b734-fc7609e864ac",
            "AlarmARN": "arn:aws:cloudwatch:us-east-1:695292474035:alarm:TargetTracking-table/terraform-state-AlarmHigh-b050c201-cf7d-4856-b734-fc7609e864ac"
        },
        {
            "AlarmName": "TargetTracking-table/terraform-state-AlarmLow-a52baf6d-efd9-4820-bd2d-f4c1e3506ff0",
            "AlarmARN": "arn:aws:cloudwatch:us-east-1:695292474035:alarm:TargetTracking-table/terraform-state-AlarmLow-a52baf6d-efd9-4820-bd2d-f4c1e3506ff0"
        },
        {
            "AlarmName": "TargetTracking-table/terraform-state-ProvisionedCapacityHigh-cb7f6b90-e416-4ac2-b7e8-61b8d5103e9c",
            "AlarmARN": "arn:aws:cloudwatch:us-east-1:695292474035:alarm:TargetTracking-table/terraform-state-ProvisionedCapacityHigh-cb7f6b90-e416-4ac2-b7e8-61b8d5103e9c"
        },
        {
            "AlarmName": "TargetTracking-table/terraform-state-ProvisionedCapacityLow-a3b4bf20-0804-4e3c-bdc3-269763e16156",
            "AlarmARN": "arn:aws:cloudwatch:us-east-1:695292474035:alarm:TargetTracking-table/terraform-state-ProvisionedCapacityLow-a3b4bf20-0804-4e3c-bdc3-269763e16156"
        }
    ]
}

 
b. Write Scaling Policy

aws application-autoscaling put-scaling-policy \\
	--region us-east-1 \\
	--service-namespace dynamodb \\
	--resource-id table/terraform-state \\
	--scalable-dimension dynamodb:table:WriteCapacityUnits \\
	--policy-name write-autoscaling-policy \\
	--policy-type TargetTrackingScaling \\
	--target-tracking-scaling-policy-configuration file://autoscaling-write-policy.json

**Output**
{
    "PolicyARN": "arn:aws:autoscaling:us-east-1:695292474035:scalingPolicy:7be568d2-ce65-4966-974d-d21f760215bd:resource/dynamodb/table/terraform-state:policyName/write-autoscaling-policy",
    "Alarms": [
        {
            "AlarmName": "TargetTracking-table/terraform-state-AlarmHigh-f050e45a-cd64-430f-8aa8-6cfb7ca271c4",
            "AlarmARN": "arn:aws:cloudwatch:us-east-1:695292474035:alarm:TargetTracking-table/terraform-state-AlarmHigh-f050e45a-cd64-430f-8aa8-6cfb7ca271c4"
        },
        {
            "AlarmName": "TargetTracking-table/terraform-state-AlarmLow-5f356463-b58a-4c6b-830f-c5da37ebcddf",
            "AlarmARN": "arn:aws:cloudwatch:us-east-1:695292474035:alarm:TargetTracking-table/terraform-state-AlarmLow-5f356463-b58a-4c6b-830f-c5da37ebcddf"
        },
        {
            "AlarmName": "TargetTracking-table/terraform-state-ProvisionedCapacityHigh-1f5aa87f-9aab-4f5f-b962-17547e2a0223",
            "AlarmARN": "arn:aws:cloudwatch:us-east-1:695292474035:alarm:TargetTracking-table/terraform-state-ProvisionedCapacityHigh-1f5aa87f-9aab-4f5f-b962-17547e2a0223"
        },
        {
            "AlarmName": "TargetTracking-table/terraform-state-ProvisionedCapacityLow-cd3ff78f-5d37-4b3c-b7a7-f6d1a073fb3f",
            "AlarmARN": "arn:aws:cloudwatch:us-east-1:695292474035:alarm:TargetTracking-table/terraform-state-ProvisionedCapacityLow-cd3ff78f-5d37-4b3c-b7a7-f6d1a073fb3f"
        }
    ]
}

Please note that these commands will also authorize Application Auto Scaling to create two AWS CloudWatch alarms - one for the upper and one for the lower boundary of the scaling target range.
 
5. Perform steps 2 – 4 on other Amazon DynamoDB tables provisioned within the current region to configure and activate their Auto Scaling status.
 
6. Update the -- region parameter and repeat the entire remediation procedure on other regions' AWS DynamoDB tables.

Still Need Help?

Come see why we are the #1 cloud management platform and why companies like Uber, Dickey’s BBQ Pit and Norwegian Cruise Line trust nOps to manage their cloud.