在Terraform中执行jsonendecode()时出现语法错误



这是我第一次出海。

我想创建一个单一的秘密管理器,其中包含3个密码与Terraform IAC的映射。为此,我尝试使用

创建aws_secretmanager_version
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)
}

其实我是跟着这个教程来理解的:https://automateinfra.com/2021/03/24/how-to-create-secrets-in-aws-secrets-manager-using-terraform-in-amazon-account/

问题是错误导致:

│
│   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.

我将随机密码替换为字符串"eeeee"并验证了几次json语法。没有什么改变。

你能帮我了解更多关于这个错误吗?

这个错误是说你在data.aws_secretsmanager_secret_version.secrets.secret_string中的字符串没有有效的JSON语法。

我必须假设data.aws_secretsmanager_secret_version.secrets.secret_string在这里与aws_secretsmanager_secret_version.sversion.secret_string相同,但我不能100%确定,因为我不是AWS秘密管理器的专家。

如果为真,那么我期望发生的事情是您插入到JSON字符串中的字符串之一包含"字符,因此导致结果字符串不是有效的JSON。

为了保证结果是有效的JSON,您应该使用jsonencode来生成该字符串而不是字符串模板,因为这样Terraform将保证在需要时为您生成有效的JSON转义:

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
})
}

上面的secret_string表达式首先构造一个Terraform对象值,然后使用jsonencode使用jsonencode文档中显示的翻译规则将其翻译成包含等效JSON对象的字符串。


这与您的问题无关,但也请注意,使用data块回读该模块使用resource块管理的相同对象是不必要的,并且可能存在问题。

在你展示的例子中是相对无害的,因为Terraform可以清楚地看到data块和resource块之间的依赖关系——但是除非这些资源类型以一种非常不寻常的方式设计,否则所有这些都是在告诉Terraform读取它已经在内存中拥有的相同对象,这可能会导致你更快地达到速率限制或使你的terraform apply变慢。

您可以参考jsondecode(aws_secretsmanager_secret_version.sversion.secret_string)直接使用参数的值分配给其他地区的配置,所以我建议这样做,而不是使用数据块,除非你知道数据源是做一些转换价值,重要的是你的下游使用。

最新更新