skip to Main Content

Trying to create a dynamoDB table via terraform within a Localstack environment running in a docker container. I have the following terraform file:

provider "aws" {
  region                  = "us-east-1"  # Change to your desired region
  access_key              = "test"       # Access key for LocalStack
  secret_key              = "test"       # Secret key for LocalStack
  skip_credentials_validation = true
  skip_requesting_account_id = true

  endpoints {
    dynamodb = "https://localhost:4566"  # LocalStack DynamoDB endpoint
  }
}


resource "aws_dynamodb_table" "users_table" {
  name           = "UserProfileTable"
  #billing_mode   = "PROVISIONED"  # Or use "PAY_PER_REQUEST" for on-demand capacity
  read_capacity  = 5
  write_capacity = 5
  hash_key = "UserID"
  range_key = "PostID"

  attribute {
    name = "UserID"
    type = "N"
  }

  attribute {
    name = "PostID"
    type = "N"
  }



  tags = {
    Name    = "dynamodb-table-1"
    Environment = "production"
  }
}

I run the localstack start -d and confirm the container is running. I navigate to the directory where the main.tf file sits. I run terraform init and then terraform apply. I get the following response:

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_dynamodb_table.users_table will be created
  + resource "aws_dynamodb_table" "users_table" {
      + arn              = (known after apply)
      + billing_mode     = "PROVISIONED"
      + hash_key         = "UserID"
      + id               = (known after apply)
      + name             = "UserProfileTable"
      + range_key        = "PostID"
      + read_capacity    = 5
      + stream_arn       = (known after apply)
      + stream_label     = (known after apply)
      + stream_view_type = (known after apply)
      + tags             = {
          + "Environment" = "production"
          + "Name"        = "dynamodb-table-1"
        }
      + tags_all         = {
          + "Environment" = "production"
          + "Name"        = "dynamodb-table-1"
        }
      + write_capacity   = 5

      + attribute {
          + name = "PostID"
          + type = "N"
        }
      + attribute {
          + name = "UserID"
          + type = "N"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.
╷
│ Warning: AWS account ID not found for provider
│ 
│   with provider["registry.terraform.io/hashicorp/aws"],
│   on dynamoDB-definition.tf line 1, in provider "aws":
│    1: provider "aws" {
│ 
│ See https://registry.terraform.io/providers/hashicorp/aws/latest/docs#skip_requesting_account_id for implications.
╵

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

I type ‘yes’ and then get stuck on aws_dynamodb_table.users_table: Still creating... forever.

I saw in this stack question that they needed to like initialize the dynamoDB services. I don’t know how to do this, and the internet suggests this isn’t necessary. Why isn’t the table ever created?

I have included the version of the various components below. Not sure if relevant.

Localstack --version: 3.1.0
awslocal --version: aws-cli/1.32.31 Python/3.11.0 Darwin/23.2.0 botocore/1.34.31
terraform --version: Terraform v1.7.2 on darwin_arm64 + provider registry.terraform.io/hashicorp/aws v5.34.0

2

Answers


  1. Try using AWS provided image DynamoDB Local!

    Here is steps to make Terraform run successfully:

    1. Create Docker Compose file docker-compose.yml:

      version: '3.8'
      services:
        dynamodb-local:
          command: "-jar DynamoDBLocal.jar -sharedDb"
          image: "amazon/dynamodb-local:latest"
          container_name: dynamodb-local
          ports:
            - "4566:8000"
      
      
    2. Change endpoint configuration in .tf file:

      endpoints {
          dynamodb = "http://localhost:4566"  # Use HTTP protocol here!
      }
      
    3. Run in terminal:

      docker-compose up -d
      terraform init
      terraform apply
      
      

      Ignore AWS account ID not found for provider warning and type yes.
      Now you should see:

      Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
      
    Login or Signup to reply.
  2. The only change needed in your Terraform configuration was this:

    provider "aws" {
      region                  = "us-east-1"  # Change to your desired region
      access_key              = "test"       # Access key for LocalStack
      secret_key              = "test"       # Secret key for LocalStack
      skip_credentials_validation = true
      skip_requesting_account_id = true
    
      endpoints {
        dynamodb = "http://localhost:4566"  # Use http endpoint here
      }
    }
    

    You can analyze the LocalStack logs to see your DynamoDB table being created:

    2024-02-01T07:51:32.556  INFO --- [   asgi_gw_0] localstack.request.aws     : AWS dynamodb.CreateTable => 200
    2024-02-01T07:51:32.571  INFO --- [   asgi_gw_1] localstack.request.aws     : AWS dynamodb.DescribeTable => 200
    2024-02-01T07:51:32.583  INFO --- [   asgi_gw_0] localstack.request.aws     : AWS dynamodb.DescribeTable => 200
    2024-02-01T07:51:32.592  INFO --- [   asgi_gw_1] localstack.request.aws     : AWS dynamodb.DescribeContinuousBackups => 200
    2024-02-01T07:51:32.609  INFO --- [   asgi_gw_0] localstack.request.aws     : AWS dynamodb.DescribeTimeToLive => 200
    2024-02-01T07:51:32.624  INFO --- [   asgi_gw_1] localstack.request.aws     : AWS dynamodb.ListTagsOfResource => 200
    

    LocalStack uses DynamoDB Local under the hood, and on top of it LocalStack has support for global tables, multi-accounts and multi-region namespacing, integration with Kinesis and DynamoDB Streams, as well as persistence.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search