Reputation: 1108
I am trying to create a BOOL type attribute to a table as follows:
resource "aws_dynamodb_table_item" "items" {
table_name = aws_dynamodb_table.dynamodb-table.name
hash_key = aws_dynamodb_table.dynamodb-table.hash_key
range_key = aws_dynamodb_table.dynamodb-table.range_key
for_each = {
"0" = {
location = "Madrid",
coordinates = ["40.49", "-3.56"],
visible = "false",
destinations = ["0", "4"]
},
"1" = {
location = "Mexico City",
coordinates = ["52.36", "13.51"],
visible = "true",
destinations = ["1", "4"]
},
}
item = <<EOF
{
"id": { "N": "${each.key}"},
"location": {"S" : "${each.value.location}"},
"coordinates": {"NS": ${jsonencode(each.value.coordinates)}},
"destinations": {"NS": ${jsonencode(each.value.destinations)}},
"visible": {"BOOL": "${each.value.visible}"}
}
EOF
}
But I get the following error:
Error: Invalid format of "item": Decoding failed: json: cannot unmarshal string into Go struct field AttributeValue.BOOL of type bool
According to the AWS documentation the attribute value seems right:
BOOL
An attribute of type Boolean. For example:
"BOOL": true
Type: Boolean
Required: No
If try to save as S (String), it works.
What am I doing wrong in this example?
Upvotes: 3
Views: 3054
Reputation: 74124
This sort of unexpected behavior is a common result of trying to build JSON strings by string concatenation. You included quotes in the template and so Terraform retained the quotes, making the boolean value appear in the result as if it were a string.
To make this more readable and to reduce the chances of that sort of mistake, you should construct the entire JSON value using jsonencode
, rather than just small portions of it:
item = jsonencode({
id = { N = each.key }
location = { S = each.value.location }
coordinates = { NS = each.value.coordinates }
destinations = { NS = each.value.destinations }
visible = { BOOL = each.value.visible }
})
This pattern makes it Terraform's job to convert the entire value to valid JSON, using the type-mapping rules described in the jsonencode
documentation. In particular, that function knows to convert a Terraform bool
value into a JSON Bool value, getting the result you needed here without the errant extra quotes. It will also ensure that the id
and location
values are properly escaped to be JSON strings, whereas your original example would've failed if either of those contained any characters that JSON considers to be "special".
Upvotes: 3
Reputation: 1108
"visible": {"BOOL": ${each.value.visible}}
without quotes! :-p
Upvotes: 3