Назначение состояния 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 по умолчанию: при каждом выполнении plan и apply 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.10/language/state/purpose/