来自 terraform 的 JSONDecode json 格式错误

JSONDecode json format error from terraform

正在尝试将从 Azure 门户创建的 sql 数据库添加到 Azure 故障转移组。

Terraform 块将调用 bash 脚本:

data "external" "database_names" {
  program = ["sh", "${path.module}/scripts/fetch_db_id.sh"]
  query = {
    db_rg            = azurerm_resource_group.mssql.name
    server_name      = azurerm_mssql_server.mssqlserver.name
  }
}

fetch_db_id.sh bash 脚本:

#!/usr/bin/env bash
# This script will get the database names at runtime.
eval "$(jq -r '@sh "export DB_RG=\(.db_rg) SERVER_NAME=\(.server_name)"')"

if [[ -z $DB_RG || -z $SERVER_NAME ]]; then
echo "Required variables DB_RG & SERVER_NAME not set" 1>&2
exit 1
fi

db_id=$(az sql db list --resource-group $DB_RG --server $SERVER_NAME --query [*].id | grep -v master 2>/dev/null)

jq -n --arg db_id "$db_id" '{"db_id":$db_id}'

unset DB_RG SERVER_NAME NODE_RG db_id

exit 0

Bash 脚本输出:运行 它在没有 terraform 的 linux VM 本地:

"db_id": "[\n "/subscriptions/my_subscription_id/resourceGroups/sql_rg/providers/Microsoft.Sql/servers/sql_server_name/databases/databaseprd-db1",\n "/subscriptions/my_subscription_id/resourceGroups/sql_rg/providers/Microsoft.Sql/servers/sql_server_name/databases/databaseprd-db2 ",\n "/subscriptions/my_subscription_id/resourceGroups/sql_rg/providers/Microsoft.Sql/servers/sql_server_name/databases/databaseprd-db3"\n]" }

用于在故障转移组内添加数据库的 Terraform 资源块:

resource "azurerm_sql_failover_group" "mssql_failover" {
  count                         = (var.enable_read_replica  && var.environment == "prd") ? 0 : 1
  name                          = var.mssql_failover_group
  resource_group_name           = azurerm_resource_group.mssql.name
  server_name                   = azurerm_mssql_server.mssqlserver.name
  databases                     = toset(jsondecode(data.external.database_names.result["db_id"]))
  partner_servers {
    id = azurerm_mssql_server.replica[0].id
  }

  read_write_endpoint_failover_policy {
    mode                        = "Automatic"
    grace_minutes               = 60
  }
  depends_on = [
    azurerm_mssql_server.replica
  ]
}

terraform 错误代码:通过 terraform jenkins 管道执行时

[1mdata.external.database_names.result["db_id"][0m 是 "[\n "/subscriptions/my_subscription_id/resourceGroups/sql_rg/providers/Microsoft.Sql/servers/sql_server_name/databases/databaseprd-db1",\n "/subscriptions/my_subscription_id/resourceGroups/sql_rg/providers/Microsoft.Sql/servers/sql_server_name/databases/databaseprd-db2",\n "/subscriptions/my_subscription_id/resourceGroups/sql_rg/providers/Microsoft.Sql/servers/sql_server_name/databases/databaseprd-db3",\n]" 调用函数“jsondecode”失败:寻找无效字符“]” 值开始

注意:当我们使用 terraform jenkins 管道 运行 时,它引入了一个额外的“,”,这可能会导致 json 错误。

我认为这里没有足够的信息可以确定,但我可以给出一个部分的、推测性的答案。

az sql db list --resource-group $DB_RG --server $SERVER_NAME --query [*].id | grep -v master 2>/dev/null

这看起来很可疑:az 命令输出 JSON,但您正在使用 grep 过滤它。 az 的输出在这里是什么样的?您希望结果有效吗 JSON?

你说我们的输出有一个你不希望的逗号。如果 az 命令输出类似以下内容,您会看到以下内容:

[
  "/blah/blah/databaseprd-db1",
  "/blah/blah/databaseprd-db2",
  "/blah/blah/databaseprd-db3",
  "/blah/blah/master"
]

grep -v master 将删除包含术语“master”的行,使您无效 JSON:

[
  "/blah/blah/databaseprd-db1",
  "/blah/blah/databaseprd-db2",
  "/blah/blah/databaseprd-db3",
]

如果你想使用 jq,你可以用

之类的东西替换 grep
jq 'map(select(index("master")|not))'