Контекст: я разрабатываю новый ресурс для своего поставщика TF.
У этого ресурса foo есть имя и соответствующая конфигурация: список пар ключ-значение (как конфиденциальных, так и неконфиденциальных).
Я определил 3 варианта:
resource "foo" "option1" {
name = "option1"
config = {
"name" = "option1"
"errors.length" = 3
"tasks.type" = "FOO"
}
config_sensitive = {
"jira.key" = "..."
"credentials.json" = "..."
}
}
resource "foo" "option2" {
name = "option2"
config = {
"name" = "option1"
"errors.length" = 3
"tasks.type" = "FOO"
"jira.key" = "..."
"credentials.json" = "..."
}
}
resource "foo" "option3" {
name = "option3"
config = file("config.json")
}
Преимущество варианта № 3 в том, что он выглядит очень читаемым, но требует, чтобы пользователь сохранил дополнительный файл json (с секретами) в той же папке (я не уверен, насколько приемлема такая настройка). Вариант № 2 выглядит заманчиво, но foo
должен принимать обновления, и если мы пометим весь блок как конфиденциальный (поскольку он может содержать секретные пары ключ-значение), функциональность обновления пострадает (пользователь не увидит ожидаемого изменения). Таким образом, вариант № 1, на мой взгляд, является победителем, поскольку он наиболее явный и позволяет нам различать чувствительные и нечувствительные атрибуты (при этом позволяя обновлять non-sensitive
). Чтение из файла всей конфигурации, вероятно, не идеально, поскольку на самом деле это не позволяет инженеру увидеть, как выглядит конфигурация, не открывая другой файл.
Также есть этот странный дублированный атрибут name
, но давайте пока его проигнорируем.
Какая конфигурация является наиболее приемлемый и используется другими поставщиками TF?
Поставщики Terraform должны обрабатывать реализацию учетных данных/авторизации, а ресурс обрабатывает конфигурацию ресурса.
например
resource "jira_issue" "some_story" {
title = "My story"
type = "story"
labels = ["someexampleonstackoverflow","jakewashere"]
}
Обратите внимание, что нет конфигурации, которая не связана с тем, что я создаю в ресурсе Terraform.
Очень приемлемо иметь какое-то задокументированное соглашение в вашем провайдере, которое откуда-то считывает учетные данные, будь то переменная ОС, файл на диске и т. д.
Например: Облачный провайдер Google будет читать переменную среды, если она заполнена, если нет, она попытается прочитать либо файл конфигурации, который находится внутри скрытого каталога в $HOME, либо попытается прочитать HTTP-сервер метаданных localhost для учетных данных.
Вариант № 3 должен быть выбран немедленно по трем причинам:
Честно говоря, варианты 1 и 2 ничем не отличаются с точки зрения управления секретами. Вы можете применить флаг sensitive
к любой вложенной структуре схемы для каждого атрибута и использовать, например. Хранилище для передачи значений на основе KV для любого из них.
Я бы выбрал 1 вместо 2 просто потому, что из вашего вопроса мне кажется, что аргументы и значения в двух блоках не имеют никакого отношения друг к другу. Поэтому имеет смысл организовать вашу схему в два отдельных блока для чистоты кода.
Я также упомяну, что если можно преобразовать credentials.json
в вашего провайдера и использовать провайдер JIRA для jira.key
, то это будет лучшим подходом как с точки зрения архитектуры кода, так и с точки зрения безопасности. Это также то, как крупные провайдеры справляются с этой ситуацией.