Тип бэкенда: 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, являются необязательными.
Учетные данные и общая конфигурация
Рекомендуем использовать переменные среды для передачи учетных данных и других конфиденциальных данных. Если вы используете -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, применяемый к файлу состояния. -
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 на производственную инфраструктуру — из-за ограничения частоты запросов, неправильно настроенных средств управления доступом или других непреднамеренных взаимодействий.
В такой организации бэкенд 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 по ссылке выше. Наиболее важные моменты:
- Политика принятия роли для каждой роли должна предоставлять доступ административной учетной записи 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.11/language/settings/backends/s3/