Назначение состояния OpenTofu
Состояние необходимо для работы OpenTofu. Часто задают вопрос, может ли OpenTofu работать без состояния или не использовать его, а при каждом запуске просто проверять ресурсы в реальном мире. Эта страница поможет объяснить, почему OpenTofu требуется состояние.
Как вы увидите из приведённых ниже причин, состояние необходимо. А в сценариях, где OpenTofu мог бы обойтись без состояния, для этого пришлось бы перенести огромную часть сложности из одного места (состояния) в другое (концепцию замены).
Соответствие реальному миру
OpenTofu требуется некая база данных для сопоставления конфигурации OpenTofu с реальным миром. Например, если в конфигурации есть ресурс resource "aws_instance" "foo", OpenTofu использует это сопоставление, чтобы знать, что ресурс resource "aws_instance" "foo" представляет собой реальный объект с идентификатором экземпляра i-abcd1234 в удалённой системе.
Для некоторых провайдеров, например AWS, OpenTofu теоретически мог бы использовать что-то вроде тегов AWS. В ранних прототипах OpenTofu вообще не было файлов состояния, и использовался этот метод. Однако вскоре мы столкнулись с проблемами. Первая серьёзная проблема была простой: не все ресурсы поддерживают теги, и не все облачные провайдеры поддерживают теги.
Поэтому для сопоставления конфигурации с ресурсами в реальном мире OpenTofu использует собственную структуру состояния.
OpenTofu ожидает, что каждый удалённый объект будет связан только с одним экземпляром ресурса в конфигурации. Если удалённый объект связан с несколькими экземплярами ресурса, сопоставление конфигурации с удалённым объектом в состоянии становится неоднозначным, и OpenTofu может вести себя неожиданным образом. OpenTofu может гарантировать взаимно однозначное соответствие при создании объектов и записи их идентификаторов в состояние. При импорте объектов, созданных вне OpenTofu, необходимо убедиться, что каждый отдельный объект импортирован только в один экземпляр ресурса.
Метаданные
Помимо сопоставления ресурсов с удалёнными объектами, OpenTofu должен также отслеживать метаданные, например зависимости ресурсов.
Обычно OpenTofu использует конфигурацию, чтобы определить порядок зависимостей. Однако при удалении ресурса из конфигурации OpenTofu должен знать, как удалить этот ресурс из удалённой системы. OpenTofu может обнаружить, что в файле состояния есть сопоставление для ресурса, которого нет в конфигурации, и запланировать его уничтожение. Но поскольку конфигурация больше не существует, определить порядок только на основании конфигурации невозможно.
Чтобы обеспечить корректную работу, OpenTofu хранит в состоянии копию последнего набора зависимостей. Теперь OpenTofu по-прежнему может определить правильный порядок уничтожения, если вы удалите из конфигурации один или несколько элементов.
Избежать этого можно было бы, если бы OpenTofu знал необходимый порядок между типами ресурсов. Например, OpenTofu мог бы знать, что серверы нужно удалять до подсетей, к которым они относятся. Однако сложность такого подхода быстро возрастает: OpenTofu пришлось бы понимать семантику порядка для каждого ресурса каждого провайдера, а также порядок между провайдерами.
По аналогичным причинам OpenTofu хранит и другие метаданные, например указатель на конфигурацию провайдера, которая использовалась с ресурсом в последний раз, если применяются несколько провайдеров с псевдонимами.
Производительность
Помимо базового сопоставления, OpenTofu хранит в состоянии кэш значений атрибутов всех ресурсов. Это наиболее необязательная возможность состояния OpenTofu, предназначенная исключительно для повышения производительности.
При выполнении tofu plan OpenTofu должен знать текущее состояние ресурсов, чтобы эффективно определять изменения, необходимые для достижения желаемой конфигурации.
Для небольших инфраструктур OpenTofu может запрашивать данные у провайдеров и синхронизировать последние значения атрибутов всех ресурсов. Это поведение OpenTofu по умолчанию: при каждом планировании и применении OpenTofu синхронизирует все ресурсы в состоянии.
Для крупных инфраструктур запрос каждого ресурса выполняется слишком медленно. Многие облачные провайдеры не предоставляют API для одновременного запроса нескольких ресурсов, а время кругового обмена данными для каждого ресурса составляет сотни миллисекунд. Кроме того, облачные провайдеры почти всегда ограничивают частоту запросов к API, поэтому OpenTofu может запрашивать лишь определённое количество ресурсов за заданный период времени. Крупные пользователи OpenTofu активно используют флаг -refresh=false, а также флаги -target/-exclude, чтобы обойти это ограничение. В таких сценариях кэшированное состояние считается достоверной записью.
Синхронизация
В конфигурации по умолчанию OpenTofu хранит состояние в файле в текущем рабочем каталоге, из которого был запущен OpenTofu. Для начала работы этого достаточно, но при использовании OpenTofu командой важно, чтобы все работали с одним и тем же состоянием, — тогда операции будут применяться к одним и тем же удалённым объектам.
Удалённое состояние — рекомендуемое решение этой проблемы. Если серверная часть состояния обладает всеми необходимыми возможностями, OpenTofu может использовать удалённую блокировку, чтобы предотвратить случайный одновременный запуск OpenTofu двумя или более пользователями и тем самым гарантировать, что каждый запуск OpenTofu начинается с последней обновлённой версии состояния.
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.11/language/state/purpose/