Prevent costly Amazon DynamoDB operations in AWS Amplify CLI projects
Tags: amplify, dynamodb, aws, serverless
Published: 2021-12-12 05:18:52

---
title: Prevent costly Amazon DynamoDB operations in AWS Amplify CLI projects
published: true
description: On how to not shoot yourself in the foot while using AWS Amplify CLI
tags: amplify, dynamodb, aws, serverless
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/yczcxebj4n8pir10ekqt.jpeg
---

The _serverless revolution_ gave birth to a new wave of developers – full-stack AWS serverless developers. Capable both on the frontend and backend, those developers can be very productive, delivering business value in days, not months.

One tool in their toolbelt might be the [_AWS Amplify CLI_](https://docs.amplify.aws/cli/), which lives under the [_AWS Amplify_](https://aws.amazon.com/amplify/) umbrella. While very powerful, when misused, it might lead to a large AWS bill at the end of the month.

This blog post will show you how to ensure that your _AWS Amplify CLI_ bootstrapped application is not running costly [_Amazon DynamoDB_](https://aws.amazon.com/dynamodb/) operations like the [`Scan` operation](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Scan.html).

## The problem with Amazon DynamoDB Scan operation

![Is it really a problem?](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5tbe4gtpzp15t253mm2s.jpeg)

Before diving into the solution, let us first learn why you might not want to run _Amazon DynamoDB_ `Scan` operations on your _Amazon DynamoDB_ tables.

The main issue is that **in most scenarios**, the _Amazon DynamoDB_ `Scan` is **wildly inefficient and costly**. The bigger your data set is, both in volume and size, the more problematic the operation can be.

The `Scan` operation will read **every item** in your table or [_secondary index_](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html) (`Scan` can retrieve up to 1 MB of data in one request). This rule applies to all `Scan` requests, even if you specify filter conditions on top of it!

Of course, that in of itself would not be a problem. It is **entirely valid to use the `Scan` operation for data migrations alike**. The situation drastically changes when developers expose **the `Scan` operation as an API endpoint** – which is what _AWS Amplify CLI_ can do.

## Unknowingly using Amazon DynamoDB `Scan` operations

How might one unknowingly expose a _Amazon DynamoDB_ `Scan` operation as an endpoint while using the _AWS Amplify CLI_?

Let us take this seemingly harmless-looking, GraphQL as an example.

```graphql
input AMPLIFY {
  globalAuthRule: AuthRule = { allow: public }
} # FOR TESTING ONLY!
type Post @model {
  id: ID!
  title: String!
}
```

When deployed according to the instructions [in the documentation](https://docs.amplify.aws/cli/graphql/overview/), various GraphQL queries, mutations, and subscriptions will be created in the [_AWS AppSync_](https://aws.amazon.com/appsync/) service.

> To deploy the _AWS Amplify_ applications using _AWS Amplify CLI_ consult the [Getting started documentation](https://docs.amplify.aws/cli/start/install/).

One of the queries is the `ListPosts` query. This query **will utilize Amazon DynamoDB `Scan` operation for data retrieval**. Not ideal in most circumstances.

I have a lot of empathy for the _AWS Amplify_ team. The idea is to hide as much complexity about AWS as possible while enabling the developers to do their job – this is a challenging problem.

In my humble opinion, while mostly doing great work, this is an area where they fall a bit short. To my best knowledge, there are **no warnings in the [documentation](https://docs.amplify.aws/cli/graphql/overview/) about this behavior**.

> The documentation around various data-modeling-related directives is excellent, though. Give it a read!

## Custom AWS CDK overrides to the rescue

So how can we use the _AWS Amplify CLI_ without worrying about using inefficient operations to access our data?

I was very happily surprised that, in the wave of the announcements before the [AWS re:Invent 2021](https://reinvent.awsevents.com/) came the [support to override Amplify-generated resources using CDK](https://aws.amazon.com/about-aws/whats-new/2021/11/aws-amplify-override-amplify-generated-resources-cdk/) – this is just what we need!

After reading the excellent [introductory blog post](https://aws.amazon.com/blogs/mobile/override-amplify-generated-backend-resources-using-cdk/), it did not take me long to make sure all _Amazon DynamoDB_ `Scan` operations are forbidden. And I was able to do it without changing my application code.

![Simplified flow](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/q0fk8abvzjrrxaouxj8v.jpeg)

### Two-step process

**The first step** is to run the _AWS Amplify CLI_ to override the GraphQL API resources. Consult the [official documentation](https://docs.amplify.aws/cli/graphql/override/) for more information.

```shell
amplify override api
```

**The second step** is to amend the `override.ts` file that the _AWS Amplify CLI_ created for us. The following is the code I've added to the `override.ts` file.

```ts
import { AmplifyApiGraphQlResourceStackTemplate } from "@aws-amplify/cli-extensibility-helper";

export function override(resources: AmplifyApiGraphQlResourceStackTemplate) {
  for (const model in resources.models) {
    const modelDDBTable = resources.models[model].modelDDBTable;
    resources.models[model].modelIamRole.policies = [
      {
        policyName: "AmplifyDenyTest",
        policyDocument: {
          Version: "2012-10-17",
          Statement: [
            {
              Effect: "Deny",
              Action: ["dynamodb:Scan"],
              // TIL: Scan can be performed on indexes
              Resource: [modelDDBTable.attrArn, `${modelDDBTable.attrArn}/*`]
            }
          ]
        }
      }
    ];
  }
}
```

Despite overriding the `policies` property for each model _AWS IAM_ role, one can still use other _Amazon DynamoDB_ operations. It is possible because the `modelIamRole` has other policies attached to it by default.

![Newly added policy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xyc1585797r6cl1vrgf7.png)

Be careful when overriding resources in your applications. You might want to do a test run before deploying anything to production.

## Closing words

You might be wondering, why bother? I would argue that having such guardrails in place, you are most likely to fall into [a pit of success](https://blog.codinghorror.com/falling-into-the-pit-of-success/) when it comes to your _Amazon DynamoDB_ access patterns.

Striving to hide complexity is an excellent mission, and _AWS Amplify CLI_ does an excellent job doing that. But it sometimes can shoot us in the foot when we are not careful.

For more similar content, follow me on Twitter - [@wm_matuszewski](https://twitter.com/wm_matuszewski).

Thank you for your valuable time.