terraform plan 'string required' dynamodb_table_item

Viewed 247

I need to add a set of strings to a dynamodb_table_item resource.

# my.tfvars

client_days = [
  "2021-05-08",               # May
  "2021-06-12", "2021-06-26", # June
]

# main.tf
variable "client_days" {
  type        = set(string)
  description = "Client days."
}

resource "aws_dynamodb_table_item" "client_days" {
  table_name = aws_dynamodb_table.periods.name
  hash_key   = "name"

  item = <<EOF
{
  "name": { "S": "client-days" },
  "days": {
      "SS" : "${client_days}"
  }
}
EOF
}

The resulting looks like this:

 32:   item = <<EOF
  33: {
  34:   "name": { "S": "client-days" },
  35:   "days": {
  36:       "SS" : "${var.client_days}"
  37:   }
  38: }
  39: EOF
    |----------------
    | var.client_days is set of string with 11 elements

Cannot include the given value in a string template: string required.

I have no clue how to solve this. I also tried converting that list into a string with join().

2 Answers

You have to use jsonencode:

resource "aws_dynamodb_table_item" "client_days" {
  table_name = "testdb"
  hash_key   = "name"

  item = <<EOF
{
  "name": { "S": "client-days" },
  "days": {
      "SS" : ${jsonencode(var.client_days)}
  }
}
EOF
}

For an argument that expects entirely JSON, it's typically best to produce the entire value with jsonencode, which then avoids various JSON syntax and Terraform templating issues:

resource "aws_dynamodb_table_item" "client_days" {
  table_name = "testdb"
  hash_key   = "name"

  item = jsonencode({
    name = {
      S = "client-days"
    }
    days = {
      SS = var.client_days
    }
  })
}

This way you can mix static data with references in your argument to jsonencode, without any need for string templating.

Related