Home > OS >  Syntax error during jsonendecode() in Terraform
Syntax error during jsonendecode() in Terraform

Time:07-11

here's my first bootle to the sea.

I want to create one single secret manager that contains a map of 3 passwords with Terraform IAC. To do that, I have tried to create a aws_secretmanager_version with

resource "aws_secretsmanager_secret" "secret_master" {
  name = "secret-master"
}

resource "aws_secretsmanager_secret_version" "sversion" {
  secret_id = aws_secretsmanager_secret.secret_master.id
  secret_string = <<EOF
   {
    "dbPassword": "${random_password.db_password.result}",
    "awsSecretAccess": "${random_password.aws_access_key_id.result}",
    "secretAccessKey": "${random_password.sec_access_key.result}"
   }
EOF
}

data "aws_secretsmanager_secret" "secret_master" {
  arn = aws_secretsmanager_secret.secret_master.arn
}
 
data "aws_secretsmanager_secret_version" "secrets" {
  secret_id = data.aws_secretsmanager_secret.secret_master.id
}
 
locals {
  secrets = jsondecode(data.aws_secretsmanager_secret_version.secrets.secret_string)
}

In fact, i followed this tutorial to understand : https://automateinfra.com/2021/03/24/how-to-create-secrets-in-aws-secrets-manager-using-terraform-in-amazon-account/

The problem is the error resulting :

│
│   on sm.tf line 60, in locals:
│   60:   secrets = jsondecode(data.aws_secretsmanager_secret_version.secrets.secret_string)
│     ├────────────────
│     │ data.aws_secretsmanager_secret_version.secrets.secret_string has a sensitive value
│
│ Call to function "jsondecode" failed: invalid character '"' after object key:value pair.

I replaced the random_passwords with strings "eeeee" and verified several times the json syntax. Nothing changed.

Could you help me to learn more about this error ?

CodePudding user response:

This error is saying that your string in data.aws_secretsmanager_secret_version.secrets.secret_string does not have valid JSON syntax.

I have to assume that data.aws_secretsmanager_secret_version.secrets.secret_string is the same as aws_secretsmanager_secret_version.sversion.secret_string here, but I'm not 100% sure since I'm not an expert on AWS secrets manager.

If that is true then I expect what's happening is that one of the strings that you interpolated into the JSON string contains a " character which is therefore causing the resulting string to not be valid JSON.

To guarantee that your result will be valid JSON, you should use jsonencode to produce that string instead of string template, because then Terraform will guarantee to generate valid JSON escaping for you when needed:

resource "aws_secretsmanager_secret_version" "sversion" {
  secret_id = aws_secretsmanager_secret.secret_master.id
  secret_string = jsonencode({
    dbPassword      = random_password.db_password.result
    awsSecretAccess = random_password.aws_access_key_id.result
    secretAccessKey = random_password.sec_access_key.result
  })
}

The above secret_string expression first constructs a Terraform object value, and then uses jsonencode to translate that into a string containing an equivalent JSON object, using the translation rules shown in the documentation for jsonencode.


This is tangential to your question, but note also that it's unnecessary and potentially problematic to read back the same object using a data block that this module is managing using a resource block.

In the example you showed is relatively harmless because Terraform can clearly see the dependency relationship between the data blocks and the resource blocks -- but unless these resource types are designed in a very unusual way all this is achieving is telling Terraform to read the same object it already had in memory anyway, which may cause you to hit rate limits faster or make your terraform apply slower.

You can refer directly to jsondecode(aws_secretsmanager_secret_version.sversion.secret_string) to use the value you assigned to that argument in other parts of the configuration, and so I would recommend doing that and not using the data blocks, unless you know that the data sources are doing some kind of transformation on that value that is important to your downstream use of it.

  • Related