Skip to content

aws_dynamodb_table: Perpetual drift when using key_schema in global_secondary_index block #46513

@reidca

Description

@reidca

Terraform and AWS Provider Version

Terraform v1.14.5
on linux_amd64
+ provider registry.terraform.io/hashicorp/archive v2.7.1
+ provider registry.terraform.io/hashicorp/aws v6.31.0

Affected Resource(s) or Data Source(s)

aws_dynamodb_table

Expected Behavior

After initial terraform apply, subsequent terraform plan should show no changes.

Actual Behavior

Every terraform plan shows the GSI will be updated in-place, with hash_key and range_key attributes being removed and re-added:

  # aws_dynamodb_table.resource_lookup_errors will be updated in-place
  ~ resource "aws_dynamodb_table" "resource_lookup_errors" {
        id                          = "lookup-errors"
        name                        = "lookup-errors"
        # (13 unchanged attributes hidden)

      - global_secondary_index {
          - hash_key           = "ResourceType" -> null
          - name               = "ResourceTypeIndex" -> null
          - non_key_attributes = [] -> null
          - projection_type    = "ALL" -> null
          - range_key          = "Timestamp" -> null
          - read_capacity      = 0 -> null
          - write_capacity     = 0 -> null

          - key_schema {
              - attribute_name = "ResourceType" -> null
              - key_type       = "HASH" -> null
            }
          - key_schema {
              - attribute_name = "Timestamp" -> null
              - key_type       = "RANGE" -> null
            }
        }
      + global_secondary_index {
          + hash_key           = (known after apply)
          + name               = "ResourceTypeIndex"
          + non_key_attributes = []
          + projection_type    = "ALL"
          + range_key          = (known after apply)
          + read_capacity      = (known after apply)
          + write_capacity     = (known after apply)

          + key_schema {
              + attribute_name = "ResourceType"
              + key_type       = "HASH"
            }
          + key_schema {
              + attribute_name = "Timestamp"
              + key_type       = "RANGE"
            }
        }
    }

### Relevant Error/Panic Output

```console

Sample Terraform Configuration

Click to expand configuration
resource "aws_dynamodb_table" "resource_lookup_errors" {
  name         = "lookup-errors"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "ErrorID"

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

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

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

  # Using recommended key_schema format
  global_secondary_index {
    name            = "ResourceTypeIndex"
    projection_type = "ALL"

    key_schema {
      attribute_name = "ResourceType"
      key_type       = "HASH"
    }

    key_schema {
      attribute_name = "Timestamp"
      key_type       = "RANGE"
    }
  }

  ttl {
    attribute_name = "ExpiresAt"
    enabled        = true
  }
}

Steps to Reproduce

  1. Create a DynamoDB table with a GSI using key_schema blocks (as shown above)
  2. Run terraform apply - table is created successfully
  3. Run terraform plan immediately after
  4. Observe perpetual drift showing GSI will be updated

Note: This occurs even on freshly created tables. We destroyed and recreated the table with key_schema format, and the drift persists immediately after creation.

Debug Logging

Click to expand log output

GenAI / LLM Assisted Development

n/a

Important Facts and References

The AWS API returns GSI configuration using the hash_key/range_key attributes in state, even when the resource was created using key_schema blocks. Terraform interprets this mismatch between state (old format) and config (new format) as drift.

Current Workaround
Use the deprecated hash_key/range_key format instead:

global_secondary_index {
  name            = "ResourceTypeIndex"
  hash_key        = "ResourceType"
  range_key       = "Timestamp"
  projection_type = "ALL"
}

### Would you like to implement a fix?

No

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugAddresses a defect in current functionality.service/dynamodbIssues and PRs that pertain to the dynamodb service.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions