Тип бэкенда: s3
Хранит состояние под заданным ключом в указанном сегменте на Amazon S3. Этот бэкенд поддерживает несколько механизмов блокировки. Предпочтительный вариант — встроенная блокировка S3 с помощью условной записи и заголовка If-None-Match. Её можно включить, задав use_lockfile=true. Другой вариант — использовать блокировку Dynamo DB, которую можно включить, задав в поле dynamodb_table имя существующей таблицы DynamoDB. Одна таблица DynamoDB может использоваться для блокировки нескольких файлов удалённого состояния. OpenTofu формирует имена ключей, включающие значения переменных bucket и key.
Настоятельно рекомендуется включить версионирование сегмента в сегменте S3, чтобы восстановить состояние в случае случайного удаления или ошибки пользователя.
Оба механизма блокировки — S3 и DynamoDB — полностью поддерживаются, и команда OpenTofu не планирует прекращать поддержку ни одного из них. Выберите механизм блокировки, который лучше всего соответствует требованиям вашей инфраструктуры.
Если вы хотите перейти с DynamoDB на встроенную блокировку состояния S3, прочитайте соответствующий раздел.
Пример конфигурации
terraform {
backend "s3" {
bucket = "mybucket"
key = "path/to/my/key"
region = "us-east-1"
}
}Предполагается, что у нас создан сегмент с именем mybucket. Состояние OpenTofu записывается в ключ path/to/my/key.
Для учетных данных доступа рекомендуется использовать частичную конфигурацию.
Разрешения для сегмента S3
Для работы OpenTofu потребуются следующие разрешения AWS IAM для целевого сегмента бэкенда:
-
s3:ListBucketдляarn:aws:s3:::mybucket -
s3:GetObjectдляarn:aws:s3:::mybucket/path/to/my/key -
s3:PutObjectдляarn:aws:s3:::mybucket/path/to/my/key -
s3:DeleteObjectдляarn:aws:s3:::mybucket/path/to/my/key
OpenTofu также могут потребоваться следующие разрешения AWS IAM для целевого сегмента бэкенда:
-
s3:PutObjectTaggingдляarn:aws:s3:::mybucket/path/to/my/key
Это показано в следующем операторе AWS IAM:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::mybucket"
},
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject", "s3:DeleteObject"],
"Resource": "arn:aws:s3:::mybucket/path/to/my/key"
}
]
}AWS позволяет управлять доступом к сегментам S3 с помощью политик IAM, прикрепленных к пользователям, группам или ролям (как в примере выше), либо политик ресурсов, прикрепленных к объектам сегмента (они выглядят похоже, но также требуют Principal, чтобы указать сущность, которой предоставлены эти разрешения). Подробнее см. в документации Amazon о управлении доступом к S3.
Разрешения для таблицы DynamoDB
Если вы используете блокировку состояния, OpenTofu потребуются следующие разрешения AWS IAM для таблицы DynamoDB (arn:aws:dynamodb:::table/mytable):
dynamodb:DescribeTabledynamodb:GetItemdynamodb:PutItemdynamodb:DeleteItem
Это показано в следующем операторе AWS IAM:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:DeleteItem"
],
"Resource": "arn:aws:dynamodb:*:*:table/mytable"
}
]
}Конфигурация источника данных
Чтобы использовать удаленное состояние S3 в другой конфигурации, воспользуйтесь источником данных terraform_remote_state.
data "terraform_remote_state" "network" {
backend = "s3"
config = {
bucket = "tofu-state-prod"
key = "network/terraform.tfstate"
region = "us-east-1"
}
}Источник данных terraform_remote_state возвращает все выходные значения корневого модуля, определенные в указанном удаленном состоянии (но не выходные значения вложенных модулей, если только они явно не выведены повторно в корневом модуле). Пример выходных данных может выглядеть так:
data.terraform_remote_state.network: id = 2016-10-29 01:57:59.780010914 +0000 UTC addresses.# = 2 addresses.0 = 52.207.220.222 addresses.1 = 54.196.78.166 backend = s3 config.% = 3 config.bucket = tofu-state-prod config.key = network/terraform.tfstate config.region = us-east-1 elb_address = web-elb-790251200.us-east-1.elb.amazonaws.com public_subnet_id = subnet-1e05dd33
Конфигурация
Для этого бэкенда необходимо настроить регион AWS и хранилище состояния S3. Другие настройки, например включение блокировки состояния с помощью DynamoDB, являются необязательными.
Варианты аутентификации
Если у вас нет особых требований, рекомендуем использовать следующие способы аутентификации:
-
Для интерактивной работы в командной строке рекомендуем использовать команду AWS CLI
aws login, чтобы получить учетные данные с помощью OAuth.Поддержка учетных данных, полученных с помощью
aws login, появилась в OpenTofu v1.12. Чтобы использовать учетные данные, выданные этой командой, убедитесь, что в конфигурации бэкенда нет параметров, связанных с учетными данными, и что в окружении не настроены другие учетные данные.Подробнее об этом способе см. в документации разработчика: Вход для локальной разработки AWS с использованием учетных данных консоли. Если ваша организация использует IAM Identity Center, вместо этого обратитесь к разделу Настройка аутентификации IAM Identity Center с помощью AWS CLI.
-
При запуске OpenTofu во временной среде выполнения, например в эфемерных рабочих средах, используемых универсальными системами CI и TACOS, рекомендуем использовать поддержку JSON Web Token (JWT) в хост-системе (также называемого «OpenID Connect» или «OIDC»), чтобы установить явное доверие между выбранной средой выполнения и подходящей ролью в вашей учетной записи AWS.
Например, в GitHub Actions можно настроить рабочий процесс, как описано в разделе Настройка OpenID Connect в облачных провайдерах. Все современные системы CI и TACOS должны предоставлять аналогичные возможности. Инструкции по их использованию ищите в документации выбранной платформы выполнения.
Некоторые платформы выполнения автоматически создают конфигурацию AWS CLI, содержащую действительный веб-токен JSON, который OpenTofu может использовать без каких-либо специальных параметров конфигурации бэкенда. В качестве альтернативы платформа может предоставлять только сам веб-токен. В этом случае конвейер должен самостоятельно создать подходящую конфигурацию, как описано в разделе Принятие роли с помощью веб-идентификации.
Если вы не можете использовать стандартные настройки AWS CLI для конфигурации веб-токена JSON, обратитесь к разделу Конфигурация принятия роли с помощью веб-идентификации, где описан встроенный альтернативный способ. Однако по возможности мы рекомендуем использовать настройки конфигурации AWS CLI вместо параметров аутентификации, специфичных для бэкенда S3.
-
Если два описанных выше способа вам недоступны, в крайнем случае можно настроить статические учетные данные в файлах учетных данных AWS CLI или с помощью переменных среды.
Эти два способа относительно просты в настройке, но поскольку они предполагают использование учетных данных с длительным сроком действия, риск их компрометации и неправомерного использования выше. Два предыдущих варианта основаны на использовании внешних данных для выдачи краткосрочных токенов сеанса, срок действия которых вскоре истекает.
Бэкенд s3 совместим со всеми различными вариантами аутентификации AWS CLI. О других возможностях можно узнать в документации разработчика «Аутентификация и учетные данные доступа для AWS CLI».
Если в конфигурации AWS CLI задано несколько профилей аутентификации, можно использовать переменную среды AWS_PROFILE или аргумент profile в конфигурации бэкенда, чтобы указать, какой профиль следует использовать OpenTofu.
OpenTofu использует AWS SDK, а не AWS CLI напрямую. Поэтому недавно добавленный в AWS CLI способ аутентификации может пока не поддерживаться в OpenTofu, но обычно его поддержка появляется в следующем минорном выпуске OpenTofu.
Учетные данные и общая конфигурация
По возможности рекомендуем хранить все параметры аутентификации в стандартных файлах конфигурации AWS CLI, используемых AWS CLI и другими интегрированными с AWS инструментами, вместо того чтобы указывать их непосредственно в аргументах бэкенда s3.
Блок backend "s3" в идеале должен содержать только аргументы region, bucket и key, задавая лишь место хранения снимков состояния, а не способ аутентификации при выполнении запросов API.
Обратите внимание: любые параметры, указанные с помощью опции -backend-config при использовании tofu init, будут сохранены на диске в файле отслеживания, который OpenTofu создает в каталоге .terraform. Благодаря этому OpenTofu сможет использовать эти параметры при выполнении других команд позднее.
Обязательны следующие параметры конфигурации:
-
region— (Обязательно) Регион AWS для сегмента S3 и таблицы DynamoDB (если используется). Также можно задать с помощью переменных средыAWS_DEFAULT_REGIONиAWS_REGION.
Необязательные параметры конфигурации:
-
iam_endpoint— (Необязательно) Устарело. Пользовательская конечная точка API AWS Identity and Access Management (IAM). Также можно задать с помощью переменной средыAWS_IAM_ENDPOINT. -
max_retries— (Необязательно) Максимальное число повторных попыток запроса AWS API при ошибке, допускающей повтор. По умолчанию — 5. -
retry_mode— (Необязательно) Определяет способ выполнения повторных попыток. Допустимые значения:standardиadaptive. Также можно задать с помощью переменной средыAWS_RETRY_MODE. -
profile— (Необязательно) Имя профиля AWS в общем файле учетных данных AWS (например,~/.aws/credentials) или общем файле конфигурации AWS (например,~/.aws/config), используемого для учетных данных и/или конфигурации. Также можно задать с помощью переменной средыAWS_PROFILE. -
shared_credentials_file— (Необязательно) Устарело. Путь к общему файлу учетных данных AWS. По умолчанию —~/.aws/credentials. -
shared_credentials_files— (Необязательно) Список путей к общим файлам учетных данных AWS. По умолчанию —~/.aws/credentials. Также можно задать с помощью переменной средыAWS_SHARED_CREDENTIALS_FILE. -
shared_config_files— (Необязательно) Список путей к общим файлам конфигурации AWS. По умолчанию —~/.aws/config. Также можно задать с помощью переменной средыAWS_SHARED_CONFIG_FILE. -
skip_s3_checksum— (Необязательно) Не добавлять контрольную сумму к входным данным при загрузке объектов S3. Полезно для API, совместимых с S3, но не являющихся AWS, которые не поддерживают проверку контрольных сумм. -
skip_credentials_validation— (Необязательно) Пропустить проверку учетных данных через API STS. -
skip_region_validation— (Необязательно) Пропустить проверку указанного имени региона. -
skip_metadata_api_check— (Необязательно) Не использовать API метаданных EC2. -
skip_requesting_account_id— (Необязательно) Не запрашивать идентификатор учетной записи. Полезно для реализаций AWS API, в которых отсутствуют API IAM, STS или API метаданных. -
sts_endpoint— (Необязательно) Устарело. Пользовательская конечная точка API AWS Security Token Service (STS). Также можно задать с помощью переменной средыAWS_STS_ENDPOINT. -
sts_region— (Необязательно) Регион AWS для STS. Если не задан, AWS будет использовать для STS тот же регион, что и для остальных операций, не относящихся к STS. -
allowed_account_ids(Необязательно): список разрешенных идентификаторов учетных записей AWS для защиты от случайного нарушения работы действующей среды. Этот параметр несовместим сforbidden_account_ids. -
forbidden_account_ids(Необязательно): список запрещенных идентификаторов учетных записей AWS для предотвращения непреднамеренного нарушения работы действующей среды. Этот параметр несовместим сallowed_account_ids. -
custom_ca_bundle— файл с пользовательскими корневыми и промежуточными сертификатами. Также можно настроить с помощью переменной средыAWS_CA_BUNDLE. -
ec2_metadata_service_endpoint— адрес используемой конечной точки службы метаданных EC2 (IMDS). Также можно задать с помощью переменной средыAWS_EC2_METADATA_SERVICE_ENDPOINT. -
ec2_metadata_service_endpoint_mode— режим взаимодействия со службой метаданных. Допустимые значения:IPv4иIPv6. Также можно задать с помощью переменной средыAWS_EC2_METADATA_SERVICE_ENDPOINT_MODE. -
http_proxy— (Необязательно) Адрес HTTP-прокси для доступа к AWS API. Также можно задать с помощью переменной средыHTTP_PROXY. -
https_proxy— (Необязательно) Адрес HTTPS-прокси для доступа к AWS API. Также можно задать с помощью переменной средыHTTPS_PROXY. -
no_proxy— (Необязательно) Значения, разделенные запятыми, указывающие узлы, для которых не следует использовать прокси при доступе к AWS API. Также можно задать с помощью переменной средыNO_PROXY. Подробнее см. здесь. -
insecure— (Необязательно) Явно разрешить бэкенду выполнять «небезопасные» запросы SSL; по умолчанию —false. -
use_dualstack_endpoint— (Необязательно) Разрешить конечную точку с поддержкой DualStack. -
use_fips_endpoint— (Необязательно) Разрешить конечную точку с поддержкой FIPS.
Следующие параметры доступны только в крайнем случае для встроенной настройки учетных данных, но мы не рекомендуем использовать их ни при каких обстоятельствах:
-
access_key— (Необязательно) Явно заданный идентификатор ключа доступа AWS. Если этот параметр задан, его значение обрабатывается аналогично переменной средыAWS_ACCESS_KEY_ID, а также необходимо задатьsecret_key. -
secret_key— (Необязательно) Явно заданный секретный ключ доступа AWS. Если этот параметр задан, его значение обрабатывается аналогично переменной средыAWS_SECRET_ACCESS_KEY. Этот параметр допустим только при наличииaccess_key. -
token— (Необязательно) Токен сеанса AWS. Если этот параметр задан, он обрабатывается аналогично переменной средыAWS_SESSION_TOKEN.
Сведения о других, более предпочтительных способах аутентификации AWS см. выше в разделе Варианты аутентификации.
Настройка конечных точек AWS API
Необязательный аргумент endpoints содержит следующие параметры:
-
s3— (Необязательно) Используйте этот параметр, чтобы задать пользовательский URL конечной точки AWS S3 API. Также можно задать с помощью переменной средыAWS_ENDPOINT_URL_S3или устаревшей переменной средыAWS_S3_ENDPOINT. -
iam— (Необязательно) Используйте этот параметр, чтобы задать пользовательский URL конечной точки AWS IAM API. Также можно задать с помощью переменной средыAWS_ENDPOINT_URL_IAMили устаревшей переменной средыAWS_IAM_ENDPOINT. -
sts— (Необязательно) Используйте этот параметр, чтобы задать пользовательский URL конечной точки AWS STS API. Также можно задать с помощью переменной средыAWS_ENDPOINT_URL_STSили устаревшей переменной средыAWS_STS_ENDPOINT. -
dynamodb— (Необязательно) Используйте этот параметр, чтобы задать пользовательский URL конечной точки AWS DynamoDB API. Также можно задать с помощью переменной средыAWS_ENDPOINT_URL_DYNAMODBили устаревшей переменной средыAWS_DYNAMODB_ENDPOINT.
terraform {
backend "s3" {
endpoints = {
dynamodb = "http://localhost:4569"
s3 = "http://localhost:4572"
}
}
}Конфигурация принятия роли
Принятие роли IAM необязательно и может быть настроено двумя способами. Предпочтительный способ — использовать аргумент assume_role; другой метод устарел.
Аргумент assume_role содержит следующие параметры:
-
role_arn— (Обязательно) Имя ресурса Amazon (ARN) принимаемой роли IAM. -
duration— (Необязательно) Задает срок действия отдельных учетных данных. Эти учетные данные обновляются автоматически; максимальный срок обновления определяется учетной записью AWS. Продолжительность указывается в формате<hours>h<minutes>m<seconds>s, при этом каждая единица измерения необязательна. Например, полтора часа можно указать как1h30mили просто90m. Продолжительность должна составлять от 15 минут (15m) до 12 часов (12h). -
external_id— (Необязательно) Внешний идентификатор, используемый при принятии роли. -
policy— (Необязательно) Представление политики IAM в формате JSON, дополнительно ограничивающей разрешения принимаемой роли IAM. -
policy_arns— (Необязательно) Набор имен ресурсов Amazon (ARN) политик IAM, дополнительно ограничивающих разрешения принимаемой роли IAM. -
session_name— (Необязательно) Имя сеанса, используемое при принятии роли. -
tags— (Необязательно) Карта тегов, связываемых с сеансом принятой роли. -
transitive_tag_keys— (Необязательно) Набор ключей тегов из сеанса принятой роли, передаваемых последующим сеансам.
Следующие параметры верхнего уровня устарели:
-
assume_role_duration_seconds— (Необязательно) Число секунд, ограничивающее продолжительность сеанса принятия роли. Вместо него используйтеassume_role.duration. -
assume_role_policy— (Необязательно) JSON политики IAM с дополнительными ограничениями разрешений принимаемой роли IAM. Вместо него используйтеassume_role.policy. -
assume_role_policy_arns— (Необязательно) Набор имен ресурсов Amazon (ARN) политик IAM с дополнительными ограничениями разрешений принимаемой роли IAM. Вместо него используйтеassume_role.policy_arns. -
assume_role_tags— (Необязательно) Карта тегов сеанса принятия роли. Вместо него используйтеassume_role.tags. -
assume_role_transitive_tag_keys— (Необязательно) Набор ключей тегов сеанса принятия роли для передачи последующим сеансам. Вместо него используйтеassume_role.transitive_tag_keys. -
external_id— (Необязательно) Внешний идентификатор, используемый при принятии роли. Вместо него используйтеassume_role.external_id. -
role_arn— (Необязательно) Имя ресурса Amazon (ARN) принимаемой роли IAM. Вместо него используйтеassume_role.role_arn. -
session_name— (Необязательно) Имя сеанса, используемое при принятии роли. Вместо него используйтеassume_role.session_name.
terraform {
backend "s3" {
bucket = "mybucket"
key = "my/key.tfstate"
region = "us-east-1"
assume_role = {
role_arn = "arn:aws:iam::ACCOUNT-ID:role/Opentofu"
}
}
}Конфигурация принятия роли с помощью веб-идентификации
Следующий блок конфигурации assume_role_with_web_identity является необязательным:
-
role_arn— (Обязательно) Имя ресурса Amazon (ARN) принимаемой роли IAM. Также можно задать с помощью переменной средыAWS_ROLE_ARN. -
duration— (Необязательно) Срок действия отдельных учетных данных. Учетные данные автоматически обновляются в пределах максимального срока, определяемого учетной записью AWS. Указывается в формате<hours>h<minutes>m<seconds>s, при этом единица измерения необязательна. Например, полтора часа можно указать как1h30mили90m. Значение должно составлять от 15 минут (15m) до 12 часов (12h). -
policy— (Необязательно) JSON политики IAM с дополнительными ограничениями разрешений принимаемой роли IAM. -
policy_arns— (Необязательно) Набор имен ресурсов Amazon (ARN) политик IAM с дополнительными ограничениями разрешений принимаемой роли IAM. -
session_name— (Необязательно) Имя сеанса, используемое при принятии роли. Также можно задать с помощью переменной средыAWS_ROLE_SESSION_NAME. -
web_identity_token— (Необязательно) Значение токена веб-идентификации от провайдера OpenID Connect (OIDC) или OAuth. Необходимо задать один из параметров:web_identity_tokenилиweb_identity_token_file. -
web_identity_token_file— (Необязательно) Файл с токеном веб-идентификации от провайдера OpenID Connect (OIDC) или OAuth. Необходимо задать один из параметров:web_identity_token_fileилиweb_identity_token. Также можно задать с помощью переменной средыAWS_WEB_IDENTITY_TOKEN_FILE.
terraform {
backend "s3" {
bucket = "mybucket"
key = "my/key.tfstate"
region = "us-east-1"
assume_role_with_web_identity = {
role_arn = "arn:aws:iam::ACCOUNT-ID:role/Opentofu"
web_identity_token = "<token value>"
}
}
}Принимаемую роль можно ограничить, указав политику.
terraform {
backend "s3" {
bucket = "mybucket"
key = "my/key.tfstate"
region = "us-east-1"
assume_role_with_web_identity = {
role_arn = "arn:aws:iam::ACCOUNT-ID:role/Opentofu"
web_identity_token = "<token value>"
policy = <<-JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": [
"arn:aws:s3:::mybucket/*",
"arn:aws:s3:::mybucket"
]
}
]
}
JSON
}
}
}Хранение состояния в S3
Обязательны следующие параметры конфигурации:
-
bucket— (Обязательно) Имя сегмента S3. -
key— (Обязательно) Путь к файлу состояния в сегменте S3. При использовании рабочего пространства, отличного от используемого по умолчанию, путь к состоянию будет иметь вид/workspace_key_prefix/workspace_name/key(см. также конфигурациюworkspace_key_prefix).
Необязательные параметры конфигурации:
-
acl- (Необязательно) Предопределённый ACL, который будет применён к файлу состояния. -
state_tags- (Необязательно) Теги, которые будут применены к объекту состояния. -
lock_tags- (Необязательно) Теги, которые будут применены к объекту блокировки. -
encrypt- (Необязательно) Включить шифрование на стороне сервера файла состояния. -
endpoint- (Необязательно) Устарело Пользовательская конечная точка для API AWS S3. Также её можно задать с помощью переменной средыAWS_S3_ENDPOINT. -
force_path_style- (Необязательно) Включить URL-адреса S3 в стиле пути (https://<HOST>/<BUCKET>вместоhttps://<BUCKET>.<HOST>). Вместо этого используйтеuse_path_style. -
use_path_style- (Необязательно) Включить URL-адреса S3 в стиле пути (https://<HOST>/<BUCKET>вместоhttps://<BUCKET>.<HOST>). -
kms_key_id- (Необязательно) Amazon Resource Name (ARN) ключа Key Management Service (KMS), который будет использоваться для шифрования состояния. Обратите внимание: если это значение указано, OpenTofu потребуются разрешенияkms:Encrypt,kms:Decryptиkms:GenerateDataKeyдля этого ключа KMS. -
sse_customer_key- (Необязательно) Ключ, который будет использоваться для шифрования состояния с помощью шифрования на стороне сервера с ключами, предоставленными клиентом (SSE-C). Это значение ключа в кодировке base64, которое после декодирования должно составлять 256 бит. Его также можно задать с помощью переменной средыAWS_SSE_CUSTOMER_KEY, что рекомендуется из-за чувствительности этого значения. Если задать его в файле OpenTofu, оно будет сохранено на диске вterraform.tfstate. -
workspace_key_prefix- (Необязательно) Префикс, добавляемый к пути состояния в бакете. Используется только при работе с рабочей областью, отличной от стандартной. По умолчанию —env:.
Блокировка состояния в DynamoDB
Следующая конфигурация является необязательной:
-
dynamodb_endpoint- (Необязательно) Устарело Пользовательская конечная точка для API AWS DynamoDB. Также её можно задать с помощью переменной средыAWS_DYNAMODB_ENDPOINT. -
dynamodb_table- (Необязательно) Имя таблицы DynamoDB, используемой для блокировки состояния и обеспечения согласованности. В таблице должен быть ключ раздела с именемLockIDтипаString. Если параметр не задан, блокировка состояния будет отключена.
Блокировка состояния в S3
-
use_lockfile- (Необязательно) Включить блокировку непосредственно в настроенном бакете для состояния.
Как упоминалось в начале этой страницы, OpenTofu рекомендует включить версионирование в бакете S3, где хранятся файлы состояния. При установке use_lockfile=true получение и снятие блокировок может привести к значительному количеству операций чтения и записи в бакете. Поэтому в бакете с включённым версионированием количество версий этого объекта может существенно возрасти. Хотя расходы на объекты блокировки должны быть незначительными, рекомендуется настроить жизненный цикл бакета S3, чтобы ограничить количество версий объекта.
При работе с рабочими областями блокировка S3 действует обычным образом: файл блокировки хранится рядом с соответствующим объектом состояния.
Переход с блокировки DynamoDB на блокировку S3
Для перехода с блокировки DynamoDB на блокировку S3 можно выполнить следующие действия:
- Новый атрибут
use_lockfile=trueможно добавить вместе сdynamodb_table:- Если указаны оба атрибута, OpenTofu сначала попытается получить блокировку в S3 и, если это удастся, попытается получить блокировку в DynamoDB. В этом случае блокировка будет считаться полученной только при успешном получении обеих блокировок (S3 и DynamoDB).
- После периода проверки работы обеих систем блокировки, если проблем не возникло, удалите атрибут
dynamodb_table. Теперь будет использоваться только блокировка S3. - Информация: Если оставить включёнными обе системы блокировки, никто не сможет получить блокировку независимо от того, используется ли у него последняя версия конфигурации.
- Можно добавить новый атрибут
use_lockfile=trueи удалитьdynamodb_table:- Это переключит блокировку с DynamoDB на S3. Внимание: если обновлённая конфигурация запускается из нескольких мест (на разных компьютерах, в конвейерах для запросов на включение изменений и т. д.), могут возникнуть проблемы, если одна устаревшая копия конфигурации использует блокировку DynamoDB, а обновлённая — блокировку S3. Это может привести к одновременному доступу к одному файлу состояния.
- После обновления состояния этим способом дайджест состояния, который OpenTofu хранил в DynamoDB (для проверки согласованности данных), устареет. Если вы захотите вернуться к блокировке DynamoDB, старый дайджест нужно будет удалить вручную.
Помните: любые изменения блока backend потребуют запуска команды tofu init -reconfigure.
Управление тегами, сохраняемыми в объектах S3
Чтобы задавать более точные правила жизненного цикла для объектов, которые OpenTofu хранит в настроенном бакете S3, можно использовать два атрибута для добавления к объектам нужных тегов.
Теги объекта состояния
Настройка state_tags в блоке backend будет добавлять настроенные теги к объекту при каждом его обновлении.
terraform {
backend "s3" {
// ...
state_tags = {
"object:type": "state"
// ...
}
}
}Теги объекта блокировки
При использовании встроенного механизма блокировки S3 через use_lockfile OpenTofu создаст объект в том же бакете, где хранится состояние. Чтобы добавить к нему теги, используйте lock_tags:
terraform {
backend "s3" {
// ...
use_lockfile = true
lock_tags = {
"object:type": "lock"
// ...
}
}
}Архитектура AWS с несколькими учётными записями
Распространённый архитектурный подход предполагает, что организация использует несколько отдельных учётных записей AWS для изоляции разных команд и сред. Например, система «staging» часто развёртывается в отдельной учётной записи AWS, отличной от учётной записи соответствующей системы «production», чтобы свести к минимуму риск влияния среды staging на инфраструктуру production — из-за ограничения частоты запросов, неправильно настроенных средств управления доступом или других непреднамеренных взаимодействий.
В такой организации бэкенд S3 можно использовать разными способами, по-разному сочетая удобство, безопасность и изоляцию. В этом разделе описан один из подходов, позволяющий найти подходящий компромисс между этими факторами и использовать функцию рабочих областей OpenTofu для удобного переключения между несколькими изолированными развёртываниями одной конфигурации.
Используйте этот раздел как отправную точку для выбора подхода, но учтите, что, вероятно, его потребуется адаптировать к уникальным стандартам и нормативным требованиям вашей организации. Возможно, также придётся скорректировать подход с учётом уже существующих практик в организации, например если для управления инфраструктурой ранее использовались другие инструменты.
OpenTofu — это инструмент администрирования инфраструктуры, поэтому в идеале инфраструктура, используемая OpenTofu, должна находиться за пределами инфраструктуры, которой управляет OpenTofu. Этого можно добиться, создав отдельную административную учётную запись AWS, в которой будут находиться учётные записи пользователей-операторов, а также инфраструктура и инструменты для управления остальными учётными записями. Изоляция общих административных инструментов от основных сред даёт ряд преимуществ: например, помогает избежать случайного повреждения административной инфраструктуры при изменении целевой инфраструктуры и снижает риск того, что злоумышленник воспользуется инфраструктурой production для получения доступа к административной инфраструктуре, обычно обладающей более широкими правами.
Настройка административной учётной записи
В административной учётной записи AWS будут находиться как минимум следующие элементы:
- Один или несколько пользователей IAM для системных администраторов, которые будут входить в систему для обслуживания инфраструктуры в других учётных записях.
- При необходимости — одна или несколько групп IAM для разделения пользователей на группы с разными уровнями доступа к другим учётным записям AWS.
- Бакет S3, в котором будут храниться файлы состояния OpenTofu для каждой рабочей области.
- Таблица DynamoDB, которая будет использоваться для блокировки, предотвращающей одновременное выполнение операций в одной рабочей области.
Укажите имя бакета S3 и имя таблицы DynamoDB в конфигурации бэкенда S3 для OpenTofu с помощью аргументов bucket и dynamodb_table соответственно. Также настройте подходящий workspace_key_prefix для хранения состояний различных рабочих областей, которые впоследствии будут созданы для этой конфигурации.
Настройка учётной записи среды
В этом разделе термин «учётная запись среды» означает одну из учётных записей, содержимым которых управляет OpenTofu, отдельно от описанной выше административной учётной записи.
Со временем в учётных записях среды появится инфраструктура, предназначенная для ваших продуктов. Кроме того, в них должны быть одна или несколько ролей IAM, предоставляющих OpenTofu достаточно прав для выполнения необходимых задач управления.
Делегирование доступа
Каждый администратор будет запускать OpenTofu с учётными данными своего пользователя IAM в административной учётной записи. Для предоставления этим пользователям доступа к ролям, созданным в каждой учётной записи среды, используется делегирование ролей IAM.
Полное описание делегирования ролей приведено в документации AWS по ссылке выше. Наиболее важные моменты:
- Политика Assume Role каждой роли должна предоставлять доступ административной учётной записи AWS, устанавливая доверительные отношения с ней, чтобы её пользователи могли принимать эту роль.
- Для пользователей или групп административной учётной записи также должна быть задана политика, устанавливающая обратное отношение и позволяющая этим пользователям или группам принимать эту роль.
Поскольку административная учётная запись предназначена только для размещения инструментов управления другими учётными записями, полезно ограничить её доступ только теми операциями, которые необходимы для принятия роли учётной записи среды и доступа к состоянию OpenTofu. Блокировка всех остальных операций исключает риск того, что из-за ошибки пользователя ресурсы staging или production будут случайно созданы в административной учётной записи.
При настройке OpenTofu используйте переменные среды или стандартный файл учётных данных ~/.aws/credentials, чтобы предоставить учётные данные IAM пользователя-администратора в административной учётной записи как бэкенду S3, так и провайдеру AWS в OpenTofu.
Используйте условную конфигурацию, чтобы передавать провайдеру AWS разные значения assume_role в зависимости от выбранной рабочей области. Например:
variable "workspace_iam_roles" {
default = {
staging = "arn:aws:iam::STAGING-ACCOUNT-ID:role/OpenTofu"
production = "arn:aws:iam::PRODUCTION-ACCOUNT-ID:role/OpenTofu"
}
}
provider "aws" {
# No credentials explicitly set here because they come from either the
# environment or the global credentials file.
assume_role {
role_arn = "${var.workspace_iam_roles[terraform.workspace]}"
}
}Если роли IAM для рабочих областей управляются централизованно и совместно используются множеством отдельных конфигураций OpenTofu, ARN ролей также можно получить с помощью источника данных, например terraform_remote_state, чтобы не дублировать эти значения.
Создание и выбор рабочих областей
Создав необходимые объекты и настроив бэкенд, выполните tofu init, чтобы инициализировать бэкенд и создать начальную рабочую область с именем «default». Эта рабочая область использоваться не будет, но OpenTofu создаёт её автоматически для удобства пользователей, которые не используют функцию рабочих областей.
Создайте рабочую область для каждого ключа, указанного выше в значении переменной workspace_iam_roles:
$ tofu workspace new staging Created and switched to workspace "staging"! ... $ tofu workspace new production Created and switched to workspace "production"! ...
Благодаря параметру assume_role в конфигурации провайдера AWS любые операции управления ресурсами AWS будут выполняться с помощью настроенной роли в соответствующей учётной записи AWS среды. Операции бэкенда, например чтение и запись состояния в S3, будут выполняться напрямую от имени пользователя-администратора в административной учётной записи.
$ tofu workspace select staging $ tofu apply ...
Запуск OpenTofu в Amazon EC2
Команды, широко использующие OpenTofu для управления инфраструктурой, часто запускают OpenTofu в автоматизированном режиме, чтобы обеспечить единообразную рабочую среду и ограничить доступ к различным секретам и другим конфиденциальным данным, которые обычно требуются конфигурациям OpenTofu.
Если OpenTofu запускается в инструменте автоматизации на экземпляре Amazon EC2, рассмотрите возможность разместить этот экземпляр в административной учётной записи и использовать профиль экземпляра вместо предложенных выше пользователей IAM администраторов. Профилю экземпляра IAM также можно предоставить доступ для межучётного делегирования с помощью политики IAM, чтобы экземпляр получил необходимые для запуска OpenTofu права.
Чтобы изолировать доступ к разным учётным записям среды, используйте отдельный экземпляр EC2 для каждой целевой учётной записи, чтобы ограничить его доступ только этой учётной записью.
Аналогичные подходы можно применять с эквивалентными функциями других вычислительных сервисов AWS, например ECS.
Защита доступа к состоянию рабочей области
При простой реализации подхода, описанного в предыдущих разделах, все пользователи могут читать и записывать состояния всех рабочих областей. Во многих случаях желательно точнее ограничить доступ к объектам состояния OpenTofu в S3, например разрешить изменять состояние production только доверенным администраторам или контролировать чтение состояния, содержащего конфиденциальную информацию.
Amazon S3 поддерживает детализированное управление доступом на уровне путей отдельных объектов с помощью политики IAM. Полное описание механизма управления доступом S3 выходит за рамки этого руководства, но ниже приведён пример политики IAM, предоставляющей доступ только к одному объекту состояния в бакете S3:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::myorg-tofu-states"
},
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::myorg-tofu-states/myapp/production/tfstate"
}
]
}Также можно настроить детализированное управление доступом к таблице DynamoDB, используемой для блокировки. Когда OpenTofu устанавливает блокировку состояния во время tofu plan, он сохраняет весь файл состояния как документ и задаёт ключ объекта S3 в качестве ключа раздела этого документа. После снятия блокировки состояния OpenTofu помещает в DynamoDB дайджест обновлённого файла состояния. Ключ похож на ключ исходного файла состояния, но имеет суффикс -md5.
В примере ниже показана простая политика IAM, позволяющая роли для операций бэкенда выполнять эти операции:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect" : "Allow",
"Action" : [
"dynamodb:DeleteItem",
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:Query",
"dynamodb:UpdateItem"
],
"Resource" : ["arn:aws:dynamodb:*:*:table/myorg-state-lock-table"],
"Condition" : {
"ForAllValues:StringEquals" : {
"dynamodb:LeadingKeys" : [
"myorg-tofu-states/myapp/production/tfstate", // during a state lock the full state file is stored with this key
"myorg-tofu-states/myapp/production/tfstate-md5" // after the lock is released a hash of the statefile's contents are stored with this key
]
}
}
}
]
}Дополнительные сведения см. в документации AWS по детализированному управлению доступом в DynamoDB.
Настройка пользовательских сведений User-Agent
Обратите внимание: эта функция необязательна.
По умолчанию базовый клиент AWS, используемый провайдером AWS для OpenTofu, формирует запросы с заголовками User-Agent, содержащими сведения о версиях OpenTofu и AWS Go SDK. Чтобы добавить в заголовки User-Agent дополнительную информацию, можно задать переменную среды TF_APPEND_USER_AGENT; её значение будет напрямую добавлено в HTTP-запросы. Например:
$ export TF_APPEND_USER_AGENT="JenkinsAgent/i-12345678 BuildID/1234 (Optional Extra Information)"
Copyright (c) The OpenTofu Authors
Copyright (c) 2014 HashiCorp, Inc.
Mozilla Public License, version 2.0
https://opentofu.org/docs/v1.12/language/settings/backends/s3/