user6826691
user6826691

Reputation: 2021

Dynamically importing secondary indexes in terraform for dynamodb

I'm trying to import a couple of dynamodb tables to terraform. I'm stuck on how to dynamically handle global secondary indexes between environments. I have a module and two state files for each environment.

How can i dynamically enter these variables using count , that change between environments,

For example in the below example there are 4 indexes but for a particular index in prod account the read capacity and write capacity changes, whereas all other variables remain constant.

ie last-index has different read and write capacity values for both prod and nonprod

How can it be implemented in terraform?

Module:

locals {
  name           = ["xxx-index","xxx-index","xxx-index","xxx-index","last-index"]
  write_capacity = [ 5,5,5,5,5]
  read_capacity  = [ 5,5,5,5,5]
  range_key      = ["xxx","xxx","xxx","xxx","xxx"]

}

  global_secondary_index {
    count           = "${length(local.name)}"
    name            = "${element(local.name, count.index)}"
    write_capacity  = "${element(local.write_capacity, count.index)"
    read_capacity   = "${element(local.read_capacity, count.index)"
    hash_key        = "userId"
    range_key       = "${element(local.range_key,count.index)}"
    projection_type = "ALL"
  }

Terraform -version Terraform v0.11.13 + provider.aws v2.25.0

Upvotes: 1

Views: 3735

Answers (1)

Martin Atkins
Martin Atkins

Reputation: 74509

There is no reasonable answer to this question for Terraform 0.11. It lacks the primitives required to describe the transform you are looking for, and it doesn't support dynamically generating nested blocks.

The closest supported thing in Terraform 0.11 would be to fix the number of indices as constant but still vary the individual parts, like this:

resource "aws_dynamodb_table" "example" {
  # ...

  global_secondary_index {
    name            = "${local.name[0]}"
    write_capacity  = "${local.write_capacity[0]}"
    read_capacity   = "${local.read_capacity[0]}"
    range_key       = "${local.range_key[0]}"
    hash_key        = "userId"
    projection_type = "ALL"
  }

  global_secondary_index {
    name            = "${local.name[1]}"
    write_capacity  = "${local.write_capacity[1]}"
    read_capacity   = "${local.read_capacity[1]}"
    range_key       = "${local.range_key[1]}"
    hash_key        = "userId"
    projection_type = "ALL"
  }

  global_secondary_index {
    name            = "${local.name[2]}"
    write_capacity  = "${local.write_capacity[2]}"
    read_capacity   = "${local.read_capacity[2]}"
    range_key       = "${local.range_key[2]}"
    hash_key        = "userId"
    projection_type = "ALL"
  }

  global_secondary_index {
    name            = "${local.name[3]}"
    write_capacity  = "${local.write_capacity[3]}"
    read_capacity   = "${local.read_capacity[3]}"
    range_key       = "${local.range_key[3]}"
    hash_key        = "userId"
    projection_type = "ALL"
  }

  global_secondary_index {
    name            = "${local.name[4]}"
    write_capacity  = "${local.write_capacity[4]}"
    read_capacity   = "${local.read_capacity[4]}"
    range_key       = "${local.range_key[4]}"
    hash_key        = "userId"
    projection_type = "ALL"
  }
}

The new Terraform 0.12 feature that was added to deal with this use-case is dynamic blocks, which allow producing zero or more blocks of a particular type based on a collection value.

For example:

locals {
  indices = {
    "xxx-index" = {
      write_capacity = 5
      read_capacity  = 5
      range_key      = "xxx"
    },
    "last-index" = {
      write_capacity = 5
      read_capacity  = 5
      range_key      = "xxx"
    },
  }
}

resource "aws_dynamodb_table" "example" {
  # ...

  dynamic "global_secondary_index" {
    for_each = local.indices
    content {
      name            = global_secondary_index.key
      write_capacity  = global_secondary_index.value.write_capacity
      read_capacity   = global_secondary_index.value.read_capacity
      range_key       = global_secondary_index.value.range_key
      hash_key        = "userId"
      projection_type = "ALL"
    }
  }
}

Upvotes: 3

Related Questions