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.