Граф ресурсов
OpenTofu строит граф зависимостей на основе конфигураций OpenTofu и обходит этот граф для создания планов, обновления состояния и других задач. На этой странице описано, какие данные содержит этот граф, какие типы узлов в нём есть и как определяются рёбра графа.
На этой странице рассматриваются технические подробности OpenTofu. Чтобы эффективно использовать OpenTofu, не обязательно разбираться в этих деталях. Здесь они описаны для тех, кто хочет узнать о них подробнее, не изучая исходный код.
Общие сведения о теории графов и краткое описание её применения в OpenTofu см. в презентации HashiCorp 2016 года Применение теории графов к инфраструктуре как коду. В этой презентации также рассматриваются некоторые идеи, похожие на изложенные в этом руководстве.
Узлы графа
В графе может быть всего несколько типов узлов. Сначала рассмотрим их, а затем объясним, как они определяются и создаются:
-
Узел ресурса — представляет один ресурс. Если задан метапараметр
count, для каждого значения count будет создан отдельный узел ресурса. Конфигурация, различия, состояние и другие данные изменяемого ресурса привязаны к этому узлу. -
Узел конфигурации провайдера — представляет этап полной настройки провайдера. На этом этапе блоку конфигурации провайдера передаются параметры, например учётные данные безопасности AWS.
-
Метаузел ресурса — представляет группу ресурсов, но сам по себе не соответствует никакому действию. Такой узел используется для удобства при работе с зависимостями и для наглядного отображения графа. Он присутствует только для ресурсов, у которых значение параметра
countбольше 1.
При визуализации конфигурации с помощью tofu graph можно увидеть все эти узлы.
Построение графа
Граф строится в несколько последовательных этапов:
-
На основе конфигурации добавляются узлы ресурсов. Если имеется diff (план) или состояние, соответствующие метаданные привязываются к каждому узлу ресурса.
-
Ресурсы связываются с провижинерами, если они определены. Это необходимо сделать после создания всех узлов ресурсов, чтобы ресурсы с одинаковым типом провижинера могли использовать одну и ту же реализацию.
-
На основе явных зависимостей из метапараметра
depends_onсоздаются рёбра между ресурсами. -
Если имеется состояние, в граф добавляются все «осиротевшие» ресурсы. Это ресурсы, которых больше нет в конфигурации, но которые присутствуют в файле состояния. У осиротевших ресурсов нет связанной с ними конфигурации, поскольку файл состояния её не хранит.
-
Ресурсы связываются с провайдерами. Для этих провайдеров создаются узлы конфигурации, а также рёбра, указывающие на зависимость ресурсов от настройки соответствующих провайдеров.
-
В конфигурациях ресурсов и провайдеров анализируются интерполяции для определения зависимостей. Ссылки на атрибуты ресурсов преобразуются в зависимости от ресурса с интерполяцией к ресурсу, на который эта интерполяция ссылается.
-
Создаётся корневой узел. Он указывает на все ресурсы и нужен для того, чтобы у графа зависимостей был один корень. При обходе графа корневой узел игнорируется.
-
Если имеется diff, выполняется обход всех узлов ресурсов и определяются ресурсы, подлежащие уничтожению. Такие узлы разбиваются на два: один узел уничтожает ресурс, а другой создаёт его (если ресурс создаётся заново). Узлы необходимо разделить, поскольку порядок уничтожения часто отличается от порядка создания, и поэтому эти действия нельзя представить одним узлом графа.
-
Проверяется, что граф не содержит циклов и имеет один корень.
Обход графа
Для обхода графа используется стандартный алгоритм поиска в глубину. Обход выполняется параллельно: обработка узла начинается, как только обработаны все его зависимости.
Параллельность ограничивается с помощью семафора, чтобы слишком большое число одновременных операций не перегружало ресурсы компьютера, на котором запущен OpenTofu. По умолчанию одновременно обрабатывается не более 10 узлов графа. Это число можно задать с помощью флага -parallelism в командах plan, apply и destroy.
Настройка -parallelism считается операцией для продвинутых пользователей и обычно не требуется при работе с OpenTofu. Она может быть полезна в некоторых особых случаях или для отладки проблем OpenTofu.
Обратите внимание: некоторые провайдеры (например, AWS) обрабатывают ограничения частоты запросов к API на более низком уровне, реализуя в соответствующих клиентах API механизм повторных попыток с постепенным увеличением интервала. Поэтому OpenTofu не использует эту возможность parallelism для непосредственной обработки ограничений частоты запросов к API.
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.10/internals/graph/