Skip to content

bug: DynamoDB - using terraform on table with on-demand capacity + GSI behaves oddly #12014

@bkindersleytrulioo

Description

@bkindersleytrulioo

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

using terraform + localstack to create a dynamodb table with pay_per_request billing mode + a GSI

  • the table creation using terraform apply works fine
  • if i subsequently run terraform plan (without any changes), it thinks it needs to update the GSI
  • if i then run terraform apply again, i get an error like deleting AWS DynamoDB Table (testddb): GSI (): operation error DynamoDB: UpdateTable, https response error StatusCode: 400, RequestID: 91c88f41-9599-402f-908c-637b5a05f713, api error ValidationException: Invalid global secondary index name

Expected Behavior

after creating a table with terraform apply, if i make no changes, then subsequent calls to terraform plan should produce no changes

How are you starting LocalStack?

With a docker-compose file

Steps To Reproduce

How are you starting localstack (e.g., bin/localstack command, arguments, or docker-compose.yml)

docker compose up -d 
version: '3.8'
services:
  localstack:
    image: localstack/localstack:latest
    ports:
      - "4566:4566"
      - "4510:4510"
    volumes:
      - ${USERPROFILE}\local-stack-data:/persisted-data  # LHS of `:` can be any path you choose (not sure if paths outside "Users" behave)
    container_name: localstack-test
    restart: always
    healthcheck:
      test:
        - CMD
        - bash
        - -c
        - awslocal sqs list-queues
      interval: 300s
      timeout: 10s
      start_period: 10s
      start_interval: 5s

Client commands (e.g., AWS SDK code snippet, or sequence of "awslocal" commands)

terraform init
terraform apply --auto-approve
terraform plan

with .tf file

provider "aws" {
    access_key = "test"
    secret_key = "test"
    region = "us-west-2"
    endpoints {
        sts = "http://localhost:4566"
        dynamodb = "http://localhost:4566"
        sqs = "http://localhost:4566"
        s3 = "http://s3.localhost.localstack.cloud:4566"
    }
}
terraform {
  required_version = ">= 1.3.6"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }
}

resource "aws_dynamodb_table" "test" {
    provider = aws
    name = "testddb"
    billing_mode = "PAY_PER_REQUEST"
    stream_enabled = false
    hash_key = "TID"
    attribute {
        name = "TID"
        type = "S"
    }
    attribute {
        name = "TRID"
        type = "S"
    }
    ttl {
        attribute_name = "ExpireAtEpochSeconds"
        enabled = true
    }
    global_secondary_index {
        name = "TransactionRecordID"
        hash_key = "TRID"
        projection_type = "ALL"
    }
    lifecycle {
        prevent_destroy = false
    }
}

Environment

- OS: Windows (my host machine)
- LocalStack:
  LocalStack version: 3.8.2.dev120
  LocalStack Docker image sha: sha256:70a953b6dd1201e00d710dc57bfcfc79ee20d6c21b798be573a8ec0e2d5f11f4
  LocalStack build date: 2024-11-15
  LocalStack build git hash: 75436efc5

Anything else?

i did an experiment where

  • i first created the table with provisioned mode, and specified read and write capacities for the table and the GSI (using terraform apply)
  • i changed the table mode to pay_per_request and removed the table's read and write capacities (but i left the capacities in the index block) and ran terraform apply
  • subsequent calls to terraform plan behaved as i expected: ie no changes to apply
  • the difference seems to be that in this case the describe-table call returns a ProvisionedThroughput element under the GlobalSecondaryIndexes[0] element, while in the first case, there is no such element [i used terraform's debug logging to determine this]
  • describe-table command against real aws (via aws cli) contains the ProvisionedThroughput element even for an on-demand billing mode table

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions