Назначение состояния 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.9/language/state/purpose/