Машиночитаемый пользовательский интерфейс
По умолчанию многие команды OpenTofu отображают вывод пользовательского интерфейса в виде неструктурированного текста, предназначенного для чтения пользователем в эмуляторе терминала. Этот текстовый поток не является стабильным интерфейсом для интеграций. Некоторые команды поддерживают флаг -json, который включает режим структурированного вывода в формате JSON с определённым интерфейсом.
Для длительно выполняющихся команд, таких как plan, apply и refresh, флаг -json выводит поток сообщений пользовательского интерфейса в формате JSON, по одному сообщению в строке. Их можно обрабатывать по одному сообщению, а интегрирующее программное обеспечение может фильтровать, объединять или изменять вывод по своему усмотрению.
Первое выведенное сообщение имеет тип version и содержит ключ ui со значением "1.0". Семантика этой версии следующая:
- Для обратно совместимых изменений или дополнений мы будем увеличивать минорную версию, например
"1.1". Чтобы сохранить прямую совместимость с будущими минорными версиями, игнорируйте свойства объектов с неизвестными именами. - Для изменений, несовместимых с предыдущими версиями, мы будем увеличивать мажорную версию, например
"2.0". Отклоняйте любые входные данные, в которых указана неподдерживаемая мажорная версия.
Мы будем вводить новые мажорные версии только в рамках гарантий совместимости OpenTofu 1.0.
Пример вывода JSON
Ниже приведён пример вывода команды tofu apply -json:
{"@level":"info","@message":"OpenTofu 1.6.0","@module":"tofu.ui","@timestamp":"2021-05-25T13:32:41.275359-04:00","tofu":"0.15.4","type":"version","ui":"0.1.0"}
{"@level":"info","@message":"random_pet.animal: Plan to create","@module":"tofu.ui","@timestamp":"2021-05-25T13:32:41.705503-04:00","change":{"resource":{"addr":"random_pet.animal","module":"","resource":"random_pet.animal","implied_provider":"random","resource_type":"random_pet","resource_name":"animal","resource_key":null},"action":"create"},"type":"planned_change"}
{"@level":"info","@message":"Plan: 1 to add, 0 to change, 0 to destroy.","@module":"tofu.ui","@timestamp":"2021-05-25T13:32:41.705638-04:00","changes":{"add":1,"change":0,"remove":0,"operation":"plan"},"type":"change_summary"}
{"@level":"info","@message":"random_pet.animal: Creating...","@module":"tofu.ui","@timestamp":"2021-05-25T13:32:41.825308-04:00","hook":{"resource":{"addr":"random_pet.animal","module":"","resource":"random_pet.animal","implied_provider":"random","resource_type":"random_pet","resource_name":"animal","resource_key":null},"action":"create"},"type":"apply_start"}
{"@level":"info","@message":"random_pet.animal: Creation complete after 0s [id=smart-lizard]","@module":"tofu.ui","@timestamp":"2021-05-25T13:32:41.826179-04:00","hook":{"resource":{"addr":"random_pet.animal","module":"","resource":"random_pet.animal","implied_provider":"random","resource_type":"random_pet","resource_name":"animal","resource_key":null},"action":"create","id_key":"id","id_value":"smart-lizard","elapsed_seconds":0},"type":"apply_complete"}
{"@level":"info","@message":"Apply complete! Resources: 1 added, 0 changed, 0 destroyed.","@module":"tofu.ui","@timestamp":"2021-05-25T13:32:41.869168-04:00","changes":{"add":1,"change":0,"remove":0,"operation":"apply"},"type":"change_summary"}
{"@level":"info","@message":"Outputs: 1","@module":"tofu.ui","@timestamp":"2021-05-25T13:32:41.869280-04:00","outputs":{"pets":{"sensitive":false,"type":"string","value":"smart-lizard"}},"type":"outputs"}Каждая строка содержит объект JSON с несколькими ключами, общими для всех сообщений. Это:
-
@level: обычно это «info», но при отображении диагностических сообщений может быть «error» или «warn» -
@message: понятное человеку краткое описание содержимого этого сообщения -
@module: всегда «tofu.ui» при отображении вывода пользовательского интерфейса -
@timestamp: временная метка RFC3339, указывающая, когда было выведено сообщение -
type: определяет тип сообщения и способ интерпретации других присутствующих ключей
Клиенты, отображающие журналы в пользовательском интерфейсе, должны обрабатывать неожиданные типы сообщений, показывая пользователю как минимум поле @message.
Сообщения будут выдаваться по мере возникновения соответствующих событий. Это означает, что сообщения, относящиеся к нескольким ресурсам, могут перемежаться (если OpenTofu работает с уровнем параллелизма выше 1). Значение объекта resource можно использовать для связывания нескольких сообщений об одном ресурсе.
Типы сообщений
Поддерживаются следующие типы сообщений:
Общие сообщения
-
version: сведения о версии OpenTofu и версии схемы, используемой для следующих сообщений -
log: неструктурированные, понятные человеку строки журнала -
diagnostic: диагностические предупреждения или сообщения об ошибках; подробнее о формате см. в документации поtofu validate
Результаты операций
-
resource_drift: описывает обнаруженное изменение отдельного ресурса, внесённое вне OpenTofu -
planned_change: описывает запланированное изменение отдельного ресурса -
change_summary: сводка всех запланированных или применённых изменений -
outputs: список всех выходных значений корневого модуля
Ход выполнения операций с ресурсами
-
apply_start,apply_progress,apply_complete,apply_errored: последовательность сообщений, показывающих ход применения изменений для отдельного ресурса -
provision_start,provision_progress,provision_complete,provision_errored: последовательность сообщений, показывающих ход выполнения отдельного шага провижинера -
refresh_start,refresh_complete: последовательность сообщений, показывающих ход обновления состояния отдельного ресурса
Сообщение о версии
Вывод команды с машиночитаемым пользовательским интерфейсом всегда начинается с сообщения version. Для этого сообщения определены следующие специфичные ключи:
-
tofu: версия OpenTofu, создавшая это сообщение -
ui: версия схемы машиночитаемого пользовательского интерфейса, определяющая смысл следующих сообщений
Пример
{
"@level": "info",
"@message": "OpenTofu 0.15.4",
"@module": "tofu.ui",
"@timestamp": "2021-05-25T13:32:41.275359-04:00",
"tofu": "0.15.4",
"type": "version",
"ui": "0.1.0"
}Дрейф ресурсов
Если во время планирования обнаружен дрейф, OpenTofu выдаст сообщение resource_drift для каждого ресурса, который изменился вне OpenTofu. Это сообщение содержит вложенный объект change со следующими ключами:
-
resource: объект с описанием адреса изменяемого ресурса; подробности см. ниже в разделе объект ресурса -
action: действие, запланированное для ресурса. Значения:update,delete.
Это сообщение не содержит сведений о точных изменениях, из-за которых было запланировано изменение. Эта информация доступна в выводе плана в формате JSON.
Пример
{
"@level": "info",
"@message": "random_pet.animal: Drift detected (update)",
"@module": "tofu.ui",
"@timestamp": "2021-05-25T13:32:41.705503-04:00",
"change": {
"resource": {
"addr": "random_pet.animal",
"module": "",
"resource": "random_pet.animal",
"implied_provider": "random",
"resource_type": "random_pet",
"resource_name": "animal",
"resource_key": null
},
"action": "update"
},
"type": "resource_drift"
}Запланированное изменение
В конце планирования или перед применением изменений OpenTofu выдаст сообщение planned_change для каждого ресурса, изменения которого необходимо применить. Это сообщение содержит вложенный объект change со следующими ключами:
-
resource: объект с описанием адреса изменяемого ресурса; подробности см. ниже в разделе объект ресурса -
previous_resource: объект с описанием предыдущего адреса ресурса, если это изменение включает перемещение, обусловленное конфигурацией -
action: действие, запланированное для ресурса. Значения:noop,create,read,update,replace,delete,move. -
reason: необязательная причина изменения, используемая только в случае, если действие —replaceилиdelete. Значения:-
tainted: ресурс помечен как повреждённый -
requested: пользователь запросил замену ресурса, например с помощью флага плана-replace -
cannot_update: изменения конфигурации требуют удалить и создать ресурс вместо его обновления -
delete_because_no_resource_config: в конфигурации нет соответствующего ресурса -
delete_because_wrong_repetition: ключ экземпляра ресурса не соответствуетcountилиfor_eachв конфигурации -
delete_because_count_index: ключ экземпляра ресурса находится вне диапазона аргументаcount -
delete_because_each_key: ключ экземпляра ресурса не включён в аргументfor_each -
delete_because_no_module: содержащий его экземпляр модуля отсутствует в конфигурации
-
Это сообщение не содержит сведений о точных изменениях, из-за которых было запланировано изменение. Эта информация доступна в выводе плана в формате JSON.
Пример
{
"@level": "info",
"@message": "random_pet.animal: Plan to create",
"@module": "tofu.ui",
"@timestamp": "2021-05-25T13:32:41.705503-04:00",
"change": {
"resource": {
"addr": "random_pet.animal",
"module": "",
"resource": "random_pet.animal",
"implied_provider": "random",
"resource_type": "random_pet",
"resource_name": "animal",
"resource_key": null
},
"action": "create"
},
"type": "planned_change"
}Сводка изменений
По завершении операции планирования или применения OpenTofu выводит сводку изменений. Оба типа сообщений содержат объект changes со следующими ключами:
-
add: количество создаваемых ресурсов (в том числе в рамках замены) -
change: количество ресурсов, изменяемых на месте -
remove: количество удаляемых ресурсов (в том числе в рамках замены) -
operation: одно из значенийplan,applyилиdestroy
Пример
{
"@level": "info",
"@message": "Apply complete! Resources: 1 added, 0 changed, 0 destroyed.",
"@module": "tofu.ui",
"@timestamp": "2021-05-25T13:32:41.869168-04:00",
"changes": {
"add": 1,
"change": 0,
"remove": 0,
"operation": "apply"
},
"type": "change_summary"
}Выходные значения
После успешного планирования или применения сообщение типа outputs содержит значения всех выходных значений корневого модуля. Это сообщение содержит объект outputs, ключами которого являются имена выходных значений. Объекты выходных значений содержат следующие ключи:
-
action: для планируемых выходных значений — действие, которое будет выполнено. Значения:noop,create,update,delete -
value: для применённых выходных значений — значение, закодированное в JSON -
type: для применённых выходных значений — определённый тип HCL значения -
sensitive: логическое значениеtrue, если выходное значение является конфиденциальным и по умолчанию должно быть скрыто в пользовательском интерфейсе
Обратите внимание, что выходные значения sensitive по-прежнему содержат поле value, и интегрирующее программное обеспечение должно учитывать значение признака конфиденциальности в соответствии с конкретным сценарием использования.
Пример
{
"@level": "info",
"@message": "Outputs: 1",
"@module": "tofu.ui",
"@timestamp": "2021-05-25T13:32:41.869280-04:00",
"outputs": {
"pets": {
"sensitive": false,
"type": "string",
"value": "smart-lizard"
}
},
"type": "outputs"
}Сообщения об операциях
Операции OpenTofu с ресурсом часто приводят к появлению нескольких сообщений. К их типам относятся:
-
apply_start: начало применения изменений для ресурса -
apply_progress: периодический вывод прошедшего времени -
apply_complete: успешное завершение операции -
apply_errored: обнаружение ошибки во время операции -
provision_start: начало шага провижинера -
provision_progress: вывод провижинера -
provision_complete: успешное выполнение провижининга -
provision_errored: обнаружение ошибки во время провижининга -
refresh_start: чтение ресурса во время обновления состояния -
refresh_complete: успешное обновление состояния
Каждое из этих сообщений содержит объект hook с набором полей, различающимся в зависимости от типа сообщения. Все обработчики содержат объект resource, который указывает, к какому ресурсу относится операция.
Начало применения
Объект hook сообщения apply_start содержит следующие ключи:
-
resource: объектresource, указывающий ресурс -
action: действие, которое будет выполнено для ресурса. Значения:noop,create,read,update,replace,delete -
id_keyиid_value: пара «ключ/значение», используемая для идентификации этого экземпляра ресурса; опускается, если значение неизвестно
Пример
{
"@level": "info",
"@message": "random_pet.animal: Creating...",
"@module": "tofu.ui",
"@timestamp": "2021-05-25T13:32:41.825308-04:00",
"hook": {
"resource": {
"addr": "random_pet.animal",
"module": "",
"resource": "random_pet.animal",
"implied_provider": "random",
"resource_type": "random_pet",
"resource_name": "animal",
"resource_key": null
},
"action": "create"
},
"type": "apply_start"
}Ход применения
Объект hook сообщения apply_progress содержит следующие ключи:
-
resource: объектresource, указывающий ресурс -
action: выполняемое для ресурса действие. Значения:noop,create,read,update,replace,delete -
elapsed_seconds: время, прошедшее с начала операции применения, в виде целого числа секунд
Пример
{
"@level": "info",
"@message": "null_resource.none[4]: Still creating... [30s elapsed]",
"@module": "tofu.ui",
"@timestamp": "2021-03-17T09:34:26.222465-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[4]",
"module": "",
"resource": "null_resource.none[4]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 4
},
"action": "create",
"elapsed_seconds": 30
},
"type": "apply_progress"
}Применение завершено
Объект hook сообщения apply_complete содержит следующие ключи:
-
resource: объектresource, указывающий ресурс -
action: выполненное для ресурса действие. Значения:noop,create,read,update,replace,delete -
id_keyиid_value: пара «ключ/значение», используемая для идентификации этого экземпляра ресурса; опускается, если значение неизвестно -
elapsed_seconds: время, прошедшее с начала операции применения, в виде целого числа секунд
Пример
{
"@level": "info",
"@message": "random_pet.animal: Creation complete after 0s [id=smart-lizard]",
"@module": "tofu.ui",
"@timestamp": "2021-05-25T13:32:41.826179-04:00",
"hook": {
"resource": {
"addr": "random_pet.animal",
"module": "",
"resource": "random_pet.animal",
"implied_provider": "random",
"resource_type": "random_pet",
"resource_name": "animal",
"resource_key": null
},
"action": "create",
"id_key": "id",
"id_value": "smart-lizard",
"elapsed_seconds": 0
},
"type": "apply_complete"
}Ошибка при применении
Объект hook сообщения apply_complete содержит следующие ключи:
-
resource: объектresource, указывающий ресурс -
action: выполненное для ресурса действие. Значения:noop,create,read,update,replace,delete -
elapsed_seconds: время, прошедшее с начала операции применения, в виде целого числа секунд
Подробное описание ошибки будет выведено в отдельном сообщении diagnostic.
Пример
{
"@level": "info",
"@message": "null_resource.none[0]: Creation errored after 10s",
"@module": "tofu.ui",
"@timestamp": "2021-03-26T16:38:54.013910-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"action": "create",
"elapsed_seconds": 10
},
"type": "apply_errored"
}Начало провижининга
Объект hook сообщения provision_start содержит следующие ключи:
-
resource: объектresource, указывающий ресурс -
provisioner: тип провижинера
Пример
{
"@level": "info",
"@message": "null_resource.none[0]: Provisioning with 'local-exec'...",
"@module": "tofu.ui",
"@timestamp": "2021-03-26T16:38:43.997431-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"provisioner": "local-exec"
},
"type": "provision_start"
}Ход провижининга
Объект hook сообщения provision_progress содержит следующие ключи:
-
resource: объектresource, указывающий ресурс -
provisioner: тип провижинера -
output: журнал вывода провижинера
Для каждой полученной от провижинера строки журнала выводится отдельное сообщение provision_progress.
Пример
{
"@level": "info",
"@message": "null_resource.none[0]: (local-exec): Executing: [\"/bin/sh\" \"-c\" \"sleep 10 && exit 1\"]",
"@module": "tofu.ui",
"@timestamp": "2021-03-26T16:38:43.997869-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"provisioner": "local-exec",
"output": "Executing: [\"/bin/sh\" \"-c\" \"sleep 10 && exit 1\"]"
},
"type": "provision_progress"
}Провижининг завершён
Объект hook сообщения provision_complete содержит следующие ключи:
-
resource: объектresource, указывающий ресурс -
provisioner: тип провижинера
Пример
{
"@level": "info",
"@message": "null_resource.none[0]: (local-exec) Provisioning complete",
"@module": "tofu.ui",
"@timestamp": "2021-03-17T09:34:06.239043-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"provisioner": "local-exec"
},
"type": "provision_complete"
}Ошибка при провижининге
Объект hook сообщения provision_errored содержит следующие ключи:
-
resource: объектresource, указывающий ресурс -
provisioner: тип провижинера
Пример
{
"@level": "info",
"@message": "null_resource.none[0]: (local-exec) Provisioning errored",
"@module": "tofu.ui",
"@timestamp": "2021-03-26T16:38:54.013572-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"provisioner": "local-exec"
},
"type": "provision_errored"
}Начало обновления состояния
Объект hook сообщения refresh_start содержит следующие ключи:
-
resource: объектresource, указывающий ресурс -
id_keyиid_value: пара «ключ/значение», используемая для идентификации этого экземпляра ресурса
Пример
{
"@level": "info",
"@message": "null_resource.none[0]: Refreshing state... [id=1971614370559474622]",
"@module": "tofu.ui",
"@timestamp": "2021-03-26T14:18:06.508915-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"id_key": "id",
"id_value": "1971614370559474622"
},
"type": "refresh_start"
}Обновление состояния завершено
Объект hook сообщения refresh_complete содержит следующие ключи:
-
resource: объектresource, указывающий ресурс -
id_keyиid_value: пара «ключ/значение», используемая для идентификации этого экземпляра ресурса
Пример
{
"@level": "info",
"@message": "null_resource.none[0]: Refresh complete [id=1971614370559474622]",
"@module": "tofu.ui",
"@timestamp": "2021-03-26T14:18:06.509371-04:00",
"hook": {
"resource": {
"addr": "null_resource.none[0]",
"module": "",
"resource": "null_resource.none[0]",
"implied_provider": "null",
"resource_type": "null_resource",
"resource_name": "none",
"resource_key": 0
},
"id_key": "id",
"id_value": "1971614370559474622"
},
"type": "refresh_complete"
}Объект ресурса
Объект resource представляет собой разложенную структуру, описывающую адрес ресурса в конфигурации. Он используется для определения ресурса, к которому относится данное сообщение. Объект содержит следующие ключи:
-
addr: полный уникальный адрес ресурса в виде строки -
module: адрес модуля, содержащего ресурс, в форматеmodule.foo.module.barили пустая строка для ресурса корневого модуля -
resource: адрес относительно модуля; для ресурсов корневого модуля он совпадает сaddr -
resource_type: тип ресурса, к которому относится адрес -
resource_name: метка имени ресурса -
resource_key: ключ адреса (значениеcountилиfor_each) либоnull, если не используется ни одно из них -
implied_provider: тип провайдера, определяемый типом ресурса; он может не соответствовать провайдеру ресурса, если используются псевдонимы провайдеров
Пример
{
"addr": "module.pets.random_pet.pet[\"friend\"]",
"module": "module.pets",
"resource": "random_pet.pet[\"friend\"]",
"implied_provider": "random",
"resource_type": "random_pet",
"resource_name": "pet",
"resource_key": "friend"
}Сообщения о тестировании
При запуске тестов OpenTofu выводится несколько сообщений. К их типам относятся:
-
test_abstract: сводка по найденным файлам и тестам -
test_file: сводка выполнения файла тестов -
test_run: сводка выполнения тестов -
test_summary: сводка общего состояния и статистики выполнения файлов тестов
Общая информация о тестах
Объект test_abstract сообщения test_abstract содержит динамические ключи, составленные из имени файла тестов:
-
main.tftest.hcl: список тестов, найденных в файле тестов
Пример
{
"@level": "info",
"@message": "Found 1 file and 1 run block",
"@module": "tofu.ui",
"@timestamp": "2024-04-20T17:24:48.418126+10:00",
"test_abstract": {
"main.tftest.hcl": [
"test"
]
},
"type": "test_abstract"
}Файл тестов
Объект test_file сообщения test_file содержит следующие ключи:
-
path: относительный путь к файлу тестов -
status: общий статус выполнения тестов
Пример
{
"@level": "info",
"@message": "main.tftest.hcl... pass",
"@module": "tofu.ui",
"@testfile": "main.tftest.hcl",
"@timestamp": "2024-04-20T17:24:48.588473+10:00",
"test_file": {
"path": "main.tftest.hcl",
"status": "pass"
},
"type": "test_file"
}Запуск теста
Объект сообщения test_run test_run содержит следующие ключи:
-
path: относительный путь к файлу теста -
run: название выполненного теста -
status: общий статус выполнения теста
Пример
{
"@level": "info",
"@message": " \"test\"... pass",
"@module": "tofu.ui",
"@testfile": "main.tftest.hcl",
"@testrun": "test",
"@timestamp": "2024-04-20T17:24:48.588519+10:00",
"test_run": {
"path": "main.tftest.hcl",
"run": "test",
"status": "pass"
},
"type": "test_run"
}Сводка по тестам
Объект сообщения test_summary test_summary содержит следующие ключи:
-
status: общий статус всех выполненных тестов -
passed: общее количество успешно пройденных тестов -
failed: общее количество не пройденных тестов -
errored: общее количество тестов с ошибками -
skipped: общее количество пропущенных тестов
Пример
{
"@level": "info",
"@message": "Success! 1 passed, 0 failed.",
"@module": "tofu.ui",
"@timestamp": "2024-04-20T17:24:48.716977+10:00",
"test_summary": {
"status": "pass",
"passed": 1,
"failed": 0,
"errored": 0,
"skipped": 0
},
"type": "test_summary"
}
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.10/internals/machine-readable-ui/