Тип бэкенда: s3
Хранит состояние по заданному ключу в указанном бакете Amazon S3. Этот бэкенд поддерживает несколько механизмов блокировки. Предпочтительный механизм — встроенная блокировка S3 с помощью условной записи и заголовка If-None-Match. Её можно включить, задав use_lockfile=true. Другой вариант — блокировка с помощью Dynamo DB; её можно включить, указав в поле dynamodb_table имя существующей таблицы DynamoDB. Одну таблицу DynamoDB можно использовать для блокировки нескольких файлов удалённого состояния. OpenTofu создаёт имена ключей, включающие значения переменных bucket и key.
Настоятельно рекомендуем включить версионирование бакета S3, чтобы можно было восстановить состояние в случае случайного удаления или человеческой ошибки.
Для плавного перехода на блокировку 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
Это показано в следующем операторе 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, являются необязательными.
Учётные данные и общая конфигурация
Рекомендуем использовать переменные среды для передачи учётных данных и других конфиденциальных данных. Если вы используете -backend-config или указываете эти значения непосредственно в конфигурации, OpenTofu включит их как в подкаталог .terraform, так и в файлы плана. Подробности см. в разделе «Учётные данные и конфиденциальные данные».
Обязательны следующие параметры конфигурации:
-
region— (Обязательно) регион AWS для бакета S3 и таблицы DynamoDB (если используется). Также можно задать с помощью переменных средыAWS_DEFAULT_REGIONиAWS_REGION.
Необязательны следующие параметры конфигурации:
-
access_key— (Необязательно) ключ доступа AWS. Если он настроен, необходимо также настроитьsecret_key. Также можно задать с помощью переменной средыAWS_ACCESS_KEY_ID, общего файла учётных данных AWS (например,~/.aws/credentials) или общего файла конфигурации AWS (например,~/.aws/config). -
secret_key— (Необязательно) ключ доступа AWS. Если он настроен, необходимо также настроитьaccess_key. Также можно задать с помощью переменной средыAWS_SECRET_ACCESS_KEY, общего файла учётных данных AWS (например,~/.aws/credentials) или общего файла конфигурации AWS (например,~/.aws/config). -
iam_endpoint— (Необязательно) Устарело. Пользовательская конечная точка API AWS Identity and Access Management (IAM). Также можно задать с помощью переменной средыAWS_IAM_ENDPOINT. -
max_retries— (Необязательно) Максимальное количество повторных попыток запроса к API AWS при ошибке, допускающей повтор. По умолчанию — 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— (Необязательно) Не запрашивать идентификатор учётной записи. Полезно для реализаций API AWS, не имеющих API IAM, STS или API метаданных. -
sts_endpoint— (Необязательно) Устарело. Пользовательская конечная точка API AWS Security Token Service (STS). Также можно задать с помощью переменной средыAWS_STS_ENDPOINT. -
sts_region— (Необязательно) Регион AWS для STS. Если не задан, AWS будет использовать для STS тот же регион, что и для других операций, не связанных с STS. -
token— (Необязательно) Токен многофакторной аутентификации (MFA). Также можно задать с помощью переменной средыAWS_SESSION_TOKEN. -
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-прокси для доступа к API AWS. Также можно задать с помощью переменной средыHTTP_PROXY. -
https_proxy— (Необязательно) адрес HTTPS-прокси для доступа к API AWS. Также можно задать с помощью переменной средыHTTPS_PROXY. -
no_proxy— (Необязательно) Значения, разделённые запятыми, указывающие узлы, для которых не следует использовать прокси при доступе к API AWS. Также можно задать с помощью переменной средыNO_PROXY. Дополнительные сведения см. здесь. -
insecure— (Необязательно) Явно разрешить бэкенду выполнять «небезопасные» запросы SSL; по умолчанию —false. -
use_dualstack_endpoint— (Необязательно) Использовать конечную точку с поддержкой DualStack. -
use_fips_endpoint— (Необязательно) Использовать конечную точку с поддержкой FIPS.
Настройка конечных точек API AWS
Необязательный аргумент endpoints содержит следующие параметры:
-
s3— (Необязательно) Используется для задания пользовательского URL конечной точки API AWS S3. Также можно задать с помощью переменной средыAWS_ENDPOINT_URL_S3или устаревшей переменной средыAWS_S3_ENDPOINT. -
iam— (Необязательно) Используется для задания пользовательского URL конечной точки API AWS IAM. Также можно задать с помощью переменной средыAWS_ENDPOINT_URL_IAMили устаревшей переменной средыAWS_IAM_ENDPOINT. -
sts— (Необязательно) Используется для задания пользовательского URL конечной точки API AWS STS. Также можно задать с помощью переменной средыAWS_ENDPOINT_URL_STSили устаревшей переменной средыAWS_STS_ENDPOINT. -
dynamodb— (Необязательно) Используется для задания пользовательского URL конечной точки API AWS DynamoDB. Также можно задать с помощью переменной средыAWS_ENDPOINT_URL_DYNAMODBили устаревшей переменной средыAWS_DYNAMODB_ENDPOINT.
terraform {
backend "s3" {
endpoints = {
dynamodb = "http://localhost:4569"
s3 = "http://localhost:4572"
}
}
}Конфигурация Assume Role
Использование роли IAM необязательно и может быть настроено двумя способами. Предпочтительный способ — аргумент assume_role; другой способ устарел.
Аргумент assume_role содержит следующие аргументы:
-
role_arn— (Обязательно) Amazon Resource Name (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 Resource Name (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 Resource Name (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 Resource Name (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 с удостоверением веб-идентичности
Следующий блок конфигурации assume_role_with_web_identity является необязательным:
-
role_arn— (Обязательно) Amazon Resource Name (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 Resource Name (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, применяемый к файлу состояния. -
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— (Необязательно) Включить блокировку непосредственно в настроенном бакете состояния.
Для перехода с 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.
Как упоминалось в начале этой страницы, OpenTofu рекомендует включить версионирование бакета S3, в котором хранятся файлы состояния. При задании use_lockfile=true получение и снятие блокировок приведёт к значительному увеличению числа операций чтения и записи в бакет. Поэтому в бакете с включённым версионированием количество версий такого объекта может существенно возрасти. Хотя расходы на объекты блокировки должны быть незначительными, рекомендуется настроить правила жизненного цикла бакета S3, чтобы ограничить количество версий объекта.
При использовании рабочих областей блокировка S3 работает обычным образом: файл блокировки хранится рядом с соответствующим объектом состояния.
Архитектура AWS с несколькими учётными записями
Распространённый архитектурный шаблон предполагает использование организацией нескольких отдельных учётных записей AWS для изоляции разных команд и сред. Например, система «staging» часто развёртывается в отдельной учётной записи AWS, отличной от учётной записи соответствующей рабочей системы, чтобы свести к минимуму риск влияния среды staging на рабочую инфраструктуру — из-за ограничения частоты запросов, неправильно настроенных средств управления доступом или других непредвиденных взаимодействий.
В такой организации бэкенд S3 можно использовать разными способами, выбирая различные компромиссы между удобством, безопасностью и изоляцией. В этом разделе описан один из подходов, призванный найти разумный баланс между этими факторами и позволяющий использовать функцию рабочих областей OpenTofu для удобного переключения между несколькими изолированными развёртываниями одной конфигурации.
Используйте этот раздел как отправную точку для своего подхода, но помните, что вам, вероятно, потребуется внести изменения с учётом уникальных стандартов и нормативных требований вашей организации. Возможно, также потребуется адаптировать этот подход к уже существующим в организации практикам — например, если ранее для управления инфраструктурой использовались другие инструменты.
OpenTofu — это инструмент администрирования, который управляет вашей инфраструктурой, поэтому в идеале инфраструктура, используемая OpenTofu, должна находиться вне инфраструктуры, которой управляет OpenTofu. Этого можно добиться, создав отдельную административную учетную запись AWS, содержащую учетные записи пользователей для операторов и всю инфраструктуру и инструменты, используемые для управления остальными учетными записями. Изоляция общих административных инструментов от основных сред имеет ряд преимуществ: например, она помогает избежать случайного повреждения административной инфраструктуры при изменении целевой инфраструктуры и снижает риск того, что злоумышленник воспользуется производственной инфраструктурой, чтобы получить доступ к административной инфраструктуре, которая обычно имеет более широкие привилегии.
Настройка административной учетной записи
В вашей административной учетной записи 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. Блокируя весь прочий доступ, вы снижаете риск того, что из-за ошибки пользователя ресурсы промежуточной или производственной среды будут по ошибке созданы в административной учетной записи.
При настройке 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, чтобы, например, только доверенные администраторы могли изменять производственное состояние или чтобы контролировать чтение состояния, содержащего конфиденциальную информацию.
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.10/language/settings/backends/s3/