How to Solve “property provisionedthroughput cannot be empty” Error

How to Solve "property provisionedthroughput cannot be empty"

Error Message :

Property ProvisionedThroughput cannot be empty.

Problem:

I was creating a very simple DynamoDB table with just a primary key EmployeeId using below CloudFormation Template.

AWSTemplateFormatVersion: 2010-09-09
Description: AWS CloudFormation Template To Create a DynamoDB Table

Resources:
  EmployeeTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Employee
      AttributeDefinitions:
        - 
          AttributeName: EmployeeId
          AttributeType: S

      KeySchema:
        - 
          AttributeName: EmployeeId
          KeyType: HASH
 
Outputs:
  Employee:
    Description: Table Created using this template.
    Value: !Ref EmployeeTable

And, My Stack Creation Failed With Below Error !!!

Property ProvisionedThroughput cannot be empty.

How to Solve property provisionedthroughput cannot be empty

Why This Happened?

As we know, DynamoDB being a NoSQL database, allows us to be flexible with our table schema. And, all we need to create a DynamoDB table is the Primary Key or Hash Key.

Therefore, I took the simplest possible template(above mentioned) and went ahead to create the DynamoDB table us.

However, my stack failed with property provisionedthroughput cannot be empty error.

On little bit of investigation and checking the DynamoDB CloudFormation resource AWS::DynamoDB::Table, I found that property BillingMode by default is set to PROVISIONED mode by CloudFormation.

Which means that, if you not explicitly specifying BillingMode: PAY_PER_REQUEST in your template, you must specify ProvisionedThroughput property on your table as well as all Global Secondary Indexes.

Since, I didn’t specify BillingMode explicitly in my above template, it was set to PROVISIONED by default. But I didn’t provide value for property ProvisionedThroughput either.

And that’s why my stack failed with ProvisionedThroughput empty error.

Feel free to checkout my tutorial to understand the nitty gritty of creating DynamoDB table using CloudFormation

Solution:

By this point, we know that proving value for ProvisionedThroughput will solve above error for my stack.

But, Let’s understand the root of this issue in more details.

What is BillingMode?

BillingMode actually lets you specify, how you would like to be charged for your DynamoDB table. It gives you two option.

  • PAY_PER_REQUEST : On demand Capacity
  • PROVISIONED: Provisioned Capacity

In case of PAY_PER_REQUEST, you don’t need to specify any capacity details from your end. Capacity is handled by DynamoDB on demand.

On the other hand, when BillingMode is PROVISIONED, you must set the value for property ProvisionedThroughput like below-

ProvisionedThroughput: 
  ReadCapacityUnits: 3
  WriteCapacityUnits: 3

That means, every time you are creating a DynamoDB table, think how do you want to be charged for read and write throughput. Do you want DynamoDB to handle it for your based on demand or you know how much read and write capacity you are gonna need and provide the same.

Once you know the answer, your answer for BillingMode will be either of one below.

  1. PAY_PER_REQUEST: DynamoDB handled capacity on demand
  2. PROVISIONED: You specify read and write capacity

Note: Please note that, you can not specify both BillingMode: PAY_PER_REQUEST and ProvisionedThroughput. In case of PAY_PER_REQUEST scaling is handled by DynamoDB on demand.

So Here are few option to solve above error:

1.Create DynamoDB with On Demand Capacity using CloudFormation

Since, in the beginning we didn’t specify BillingMode, by default it was set to PROVISIONED. So, lets provide the value for billing mode like –

BillingMode: PAY_PER_REQUEST

And resulting template becomes like below which works perfectly fine and creates a DynamoDB table with on demand capacity.

AWSTemplateFormatVersion: 2010-09-09
Description: AWS CloudFormation Template To Create a DynamoDB Table

Resources:
  EmployeeTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Employee
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - 
          AttributeName: EmployeeId
          AttributeType: S

      KeySchema:
        - 
          AttributeName: EmployeeId
          KeyType: HASH
 
Outputs:
  Employee:
    Description: Table Created using this template.
    Value: !Ref EmployeeTable

2. Create DynamoDB with Provisioned Capacity using CloudFormation

When you are not specifying BillingMode or specifying it to be PROVISIONED explicitly, provide the value of ProvisionedThroughput property like below-

ProvisionedThroughput: 
  ReadCapacityUnits: 3
  WriteCapacityUnits: 3

Resulting template after adding this is –

AWSTemplateFormatVersion: 2010-09-09
Description: AWS CloudFormation Template To Create a DynamoDB Table

Resources:
  EmployeeTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: Employee
      BillingMode: PROVISIONED
      ProvisionedThroughput: 
        ReadCapacityUnits: 5
        WriteCapacityUnits: 5
      AttributeDefinitions:
        - 
          AttributeName: EmployeeId
          AttributeType: S
        - 
          AttributeName: LocationId
          AttributeType: S

      KeySchema:
        - 
          AttributeName: EmployeeId
          KeyType: HASH
          
      GlobalSecondaryIndexes:
        -
          IndexName: Location-index
          KeySchema:
            - 
              AttributeName: LocationId
              KeyType: HASH
          
          Projection:
            ProjectionType: ALL
          ProvisionedThroughput: 
            ReadCapacityUnits: 3
            WriteCapacityUnits: 3
 
Outputs:
  Employee:
    Description: Table Created using this template.
    Value: !Ref EmployeeTable

Once you use above template to create your DynamoDB table, your table will be created successfully with read and write capacity unit of 5 each as specified. Also a GSI with read and write capacity of 3 as specified is created.

Conclusion

When creating a DynamoDB table using CloudFormation, BillingMode by default is set to PROVISIONED and you must specify value for property ProvisionedThroughput for your table as well as all your GSI.

In case you don’t want or need to set capacity details, set BillingMode to PAY_PER_REQUEST and things will work fine.

Hope this was helpful for you. Feel free to add a comment if you are still facing this issue.

Enjoyed the content?

Subscribe to our newsletter below to get awesome AWS learning materials delivered straight to your inbox.

Don’t forget to motivate me by-

Suggested Read:

Leave a Reply

Your email address will not be published. Required fields are marked *