Я сталкиваюсь с очень странным поведением в terraform при использовании функции jsonencode(). Я использую модуль terraform менеджера секретов AWS для создания секрета базы данных для моего приложения.
Он содержит 3 значения — хост базы данных, порт и имя. Однако, несмотря на то, что я предоставляю порт, заключенный в двойные кавычки для принудительной интерпретации строки, он создается в Secrets Manager как число. Мое приложение ожидает, что все секретные значения kv будут строками.
Код 2 ниже демонстрирует проблему. При прямой передаче вывода (как в примере secret_string_broken) он интерпретируется как число. Когда он указан явно (как в примере secret_string_working), он интерпретируется как строка, как и ожидалось.
secret_string_broken = jsonencode({
DB_HOST = "${module.db.endpoint}"
DB_PORT = "${module.db.port}"
DB_NAME = "${module.db.db_name}"
})
secret_string_working = jsonencode({
DB_HOST = "${module.db.endpoint}"
DB_PORT = "1234"
DB_NAME = "${module.db.db_name}"
})
Это проблема с использованием функции jsonencode()? Или я сталкиваюсь с каким-то странным поведением Terraform?
Я предполагаю, что terraform использует тип вывода для значения модуля.db.port и использует его для установки значения, но меня смущает, почему он игнорирует двойные кавычки.
@MarkoE Выходное значение не задано явно в самом модуле (github.com/terraform-aws-modules/terraform-aws-rds-aurora/blob/… ), и у меня возникли проблемы с выяснением точный тип вывода из исходного ресурса Terraform, используемого в модуле ( Registration.terraform.io/providers/hashicorp/aws/latest/docs/…).





Судя по документации, порт выглядит как число. Заключение его в кавычки не сделает его строкой. Вы можете попробовать использовать явное приведение типов с помощью tostring:
secret_string = jsonencode({
DB_HOST = "${module.db.endpoint}"
DB_PORT = tostring(module.db.port)
DB_NAME = "${module.db.db_name}"
})
Я также думаю, что вам не нужно заключать хост и имя в кавычки, поскольку они, вероятно, в любом случае будут строками, а это значит, что это тоже может сработать:
secret_string = jsonencode({
DB_HOST = module.db.endpoint
DB_PORT = tostring(module.db.port)
DB_NAME = module.db.db_name
})
Спасибо за пояснение. Знаете, почему заключение его в кавычки не сработает?
Я бы предположил, что это связано с тем, что до HCL2 TF, то есть версии <0.12, не было поддержки выражений первого класса для переменных, и требовалось интерполировать все переменные для разрешения их значений, а затем в >= 0.12 интерпретатор просто разрешал значения переменных внутри "" когда интерполяция не требуется без приведения к другому типу. Этот ответ гарантирует приведение выходного значения port к типу string с соответствующей функцией. Истинная интерполяция строк, вероятно, будет изменена, но это не то, что вам нужно.
Как выходное значение
portопределяется в модуле БД?