Граф ресурсов
OpenTofu строит граф зависимостей на основе конфигураций OpenTofu и обходит этот граф для создания планов, обновления состояния и выполнения других задач. На этой странице подробно описано, что содержится в этом графе, какие типы узлов в нём существуют и как определяются рёбра графа.
На этой странице рассматриваются технические подробности OpenTofu. Чтобы эффективно использовать OpenTofu, не обязательно разбираться в этих подробностях. Здесь они приведены для тех, кто хочет узнать о них, не изучая исходный код.
Общие сведения о теории графов и краткое описание её применения в OpenTofu см. в презентации HashiCorp 2016 года Применение теории графов к инфраструктуре как коду. В этой презентации также рассматриваются некоторые идеи, схожие с изложенными в следующем руководстве.
Узлы графа
В графе может существовать лишь несколько типов узлов. Сначала рассмотрим их, а затем объясним, как они определяются и создаются:
-
Узел ресурса — представляет один ресурс. Если задан метапараметр
count, для каждого элемента будет создан отдельный узел ресурса. К этому узлу привязываются конфигурация, различия, состояние и прочие данные изменяемого ресурса. -
Узел конфигурации провайдера — представляет этап полной настройки провайдера. На этом этапе провайдеру передаётся блок конфигурации провайдера, например учётные данные безопасности AWS.
-
Метаузел ресурса — представляет группу ресурсов, но сам по себе не представляет никаких действий. Он используется для удобства работы с зависимостями и для наглядности графа. Такой узел создаётся только для ресурсов, у которых значение параметра
countбольше 1.
При визуализации конфигурации с помощью tofu graph можно увидеть все эти узлы.
Построение графа
Граф строится в несколько последовательных этапов:
-
На основе конфигурации добавляются узлы ресурсов. Если присутствуют различия (план) или состояние, эти метаданные привязываются к каждому узлу ресурса.
-
Ресурсы связываются с провижионерами, если они заданы. Это необходимо делать после создания всех узлов ресурсов, чтобы ресурсы с одним и тем же типом провижионера могли использовать одну реализацию провижионера.
-
Для создания рёбер между ресурсами используются явные зависимости, заданные метапараметром
depends_on. -
Если присутствует состояние, в граф добавляются все «осиротевшие» ресурсы. К осиротевшим относятся ресурсы, которых больше нет в конфигурации, но которые присутствуют в файле состояния. У осиротевших ресурсов никогда не бывает связанной с ними конфигурации, поскольку файл состояния её не хранит.
-
Ресурсы связываются с провайдерами. Для этих провайдеров создаются узлы конфигурации, а рёбра создаются так, чтобы ресурсы зависели от настройки соответствующих провайдеров.
-
В конфигурациях ресурсов и провайдеров анализируются интерполяции для определения зависимостей. Ссылки на атрибуты ресурсов становятся зависимостями от ресурса с интерполяцией к ресурсу, на который она ссылается.
-
Создаётся корневой узел. Он указывает на все ресурсы и нужен, чтобы у графа зависимостей был один корень. При обходе графа корневой узел игнорируется.
-
Если присутствуют различия, выполняется обход всех узлов ресурсов и выявляются ресурсы, которые будут уничтожены. Такие узлы ресурсов разделяются на два: один узел уничтожает ресурс, а другой создаёт его (если ресурс пересоздаётся). Узлы необходимо разделить, поскольку порядок уничтожения часто отличается от порядка создания, поэтому представить оба действия одним узлом графа нельзя.
-
Проверяется, что граф не содержит циклов и имеет единственный корень.
Обход графа
Для обхода графа используется стандартный обход в глубину. Обход выполняется параллельно: обработка узла начинается, как только обработаны все его зависимости.
Степень параллелизма ограничивается с помощью семафора, чтобы слишком большое число одновременных операций не перегружало ресурсы компьютера, на котором запущен 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.12/internals/graph/