- OpenTofu言語
- OpenTofu設定
- バックエンド
- s3
バックエンドタイプ: s3
Amazon S3上の指定されたバケット内の指定されたキーとして状態を保存します。このバックエンドは、Dynamo DBを介した状態ロックと整合性チェックもサポートしています。これは、dynamodb_table
フィールドを既存のDynamoDBテーブル名に設定することで有効にできます。単一のDynamoDBテーブルを使用して、複数のリモート状態ファイルをロックできます。OpenTofuは、bucket
変数とkey
変数の値を含むキー名を生成します。
誤った削除や人的エラーが発生した場合に状態を回復できるように、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権限を必要とします。
arn:aws:s3:::mybucket
に対するs3:ListBucket
arn:aws:s3:::mybucket/path/to/my/key
に対するs3:GetObject
arn:aws:s3:::mybucket/path/to/my/key
に対するs3:PutObject
arn:aws:s3:::mybucket/path/to/my/key
に対するs3:DeleteObject
これは、次の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は、ユーザー/グループ/ロールにアタッチされたIAMポリシー(上記の例のような)またはバケットオブジェクトにアタッチされたリソースポリシー(同様ですが、どのエンティティにこれらの権限があるかを示すPrincipal
も必要)のいずれかでS3バケットへのアクセスを制御できます。詳細については、S3アクセス制御に関するAmazonのドキュメントを参照してください。
DynamoDBテーブルの権限
状態ロックを使用している場合、OpenTofuはDynamoDBテーブル(arn:aws:dynamodb:::table/mytable
)に対して次のAWS IAM権限を必要とします。
dynamodb:DescribeTable
dynamodb:GetItem
dynamodb:PutItem
dynamodb: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
- (必須) S3バケットとDynamoDBテーブル(使用されている場合)のAWSリージョン。これは、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
- (オプション) 非推奨 AWS Identity and Access Management (IAM) API のカスタムエンドポイント。これはAWS_IAM_ENDPOINT
環境変数からも取得できます。max_retries
- (オプション) 再試行可能なエラーが発生した場合に、AWS API リクエストを再試行する最大回数。デフォルトは 5 です。retry_mode
- (オプション) 再試行を試みる方法を指定します。有効な値はstandard
およびadaptive
です。これはAWS_RETRY_MODE
環境変数からも取得できます。profile
- (オプション) AWS 共有認証情報ファイル (例:~/.aws/credentials
) または AWS 共有設定ファイル (例:~/.aws/config
) 内の、認証情報や設定に使用する AWS プロファイルの名前。これは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 オブジェクトをアップロードする際に入力にチェックサムを含めません。チェックサムの検証をサポートしない AWS S3 API 以外の場合に便利です。skip_credentials_validation
- (オプション) STS API を介した認証情報の検証をスキップします。skip_region_validation
- (オプション) 提供されたリージョン名の検証をスキップします。skip_metadata_api_check
- (オプション) EC2 メタデータ API の使用をスキップします。skip_requesting_account_id
- (オプション) アカウント ID の要求をスキップします。IAM、STS API、またはメタデータ API がない AWS API の実装に便利です。sts_endpoint
- (オプション) 非推奨 AWS Security Token Service (STS) API のカスタムエンドポイント。これはAWS_STS_ENDPOINT
環境変数からも取得できます。sts_region
- (オプション) STS の AWS リージョン。設定されていない場合、AWS は STS 以外の操作と同じリージョンを STS に使用します。token
- (オプション) 多要素認証 (MFA) トークン。これはAWS_SESSION_TOKEN
環境変数からも取得できます。allowed_account_ids
(オプション): 実稼働環境での不慮の中断を防ぐために許可された AWS アカウント ID のリスト。このオプションはforbidden_account_ids
と競合します。forbidden_account_ids
(オプション): 実稼働環境での意図しない中断を防ぐために禁止された AWS アカウント ID のリスト。このオプションは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
- (オプション) AWS API にアクセスするときに使用する HTTP プロキシのアドレス。これはHTTP_PROXY
環境変数からも取得できます。https_proxy
- (オプション) AWS API にアクセスするときに使用する HTTPS プロキシのアドレス。これはHTTPS_PROXY
環境変数からも取得できます。no_proxy
- (オプション) AWS API にアクセスするときにプロキシから除外する必要があるホストを指定するコンマ区切りの値。これはNO_PROXY
環境変数からも取得できます。詳細については、こちらをご覧ください。insecure
- (オプション) バックエンドが「安全でない」SSL リクエストを実行することを明示的に許可します。デフォルトはfalse
です。use_dualstack_endpoint
- (オプション) デュアルスタック機能を持つエンドポイントを解決します。use_fips_endpoint
- (オプション) FIPS 機能を持つエンドポイントを解決します。
AWS API エンドポイントのカスタマイズ
オプションの endpoints
引数には、次のオプションが含まれています。
s3
- (オプション) AWS S3 API のカスタムエンドポイント URL を設定するために使用します。これはAWS_ENDPOINT_URL_S3
環境変数、または非推奨の環境変数AWS_S3_ENDPOINT
からも取得できます。iam
- (オプション) AWS IAM API のカスタムエンドポイント URL を設定するために使用します。これはAWS_ENDPOINT_URL_IAM
環境変数、または非推奨の環境変数AWS_IAM_ENDPOINT
からも取得できます。sts
- (オプション) AWS STS API のカスタムエンドポイント URL を設定するために使用します。これはAWS_ENDPOINT_URL_STS
環境変数、または非推奨の環境変数AWS_STS_ENDPOINT
からも取得できます。dynamodb
- (オプション) AWS DynamoDB API のカスタムエンドポイント URL を設定するために使用します。これはAWS_ENDPOINT_URL_DYNAMODB
環境変数、または非推奨の環境変数AWS_DYNAMODB_ENDPOINT
からも取得できます。
terraform {
backend "s3" {
endpoints {
dynamodb = "https://:4569"
s3 = "https://:4572"
}
}
}
ロールの引き受け構成
IAM ロールの引き受けはオプションであり、2 つの方法で構成できます。推奨される方法は、引数 assume_role
を使用することです。もう一方の方法は非推奨です。
引数 assume_role
には、次の引数が含まれています。
role_arn
- (必須) 引き受ける IAM ロールの Amazon リソースネーム (ARN)。duration
- (オプション) 個々の認証情報の有効期間を指定します。これらの認証情報は自動的に更新され、最大更新期間は AWS アカウントによって定義されます。期間は<時間>h<分>m<秒>s
の形式で指定する必要があり、各単位はオプションです。たとえば、1 時間半は1h30m
または単に90m
と表現できます。期間は 15 分 (15m) から 12 時間 (12h) の範囲内である必要があります。external_id
- (オプション) ロールを引き受けるときに使用する外部識別子。policy
- (オプション) 引き受ける IAM ロールの権限をさらに制限する IAM ポリシーの JSON 表現。policy_arns
- (オプション) 引き受ける IAM ロールの権限をさらに制限する IAM ポリシーの Amazon リソースネーム (ARN) のセット。session_name
- (オプション) ロールを引き受けるときに使用するセッション名。tags
- (オプション) 引き受けたロールセッションに関連付けるタグのマップ。transitive_tag_keys
- (オプション) 引き受けたロールセッションから後続のセッションに渡すタグキーのセット。
トップレベルの次の引数は非推奨です。
assume_role_duration_seconds
- (オプション) ロール引き受けセッションの期間を制限する秒数。代わりにassume_role.duration
を使用してください。assume_role_policy
- (オプション) 引き受ける IAM ロールの権限をさらに制限する IAM ポリシーの JSON。代わりにassume_role.policy
を使用してください。assume_role_policy_arns
- (オプション) 引き受ける IAM ロールの権限をさらに制限する IAM ポリシーの Amazon リソースネーム (ARN) のセット。代わりに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
- (オプション) 引き受ける IAM ロールの Amazon リソースネーム (ARN)。代わりに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"
}
}
}
ウェブ ID によるロールの引き受け構成
次の assume_role_with_web_identity
構成ブロックはオプションです。
role_arn
- (必須) 引き受ける IAM ロールの Amazon リソースネーム (ARN)。AWS_ROLE_ARN
環境変数でも設定できます。duration
- (オプション) 個々の認証情報が有効になる期間。認証情報は、AWS アカウントで定義された最大値まで自動的に更新されます。<時間>h<分>m<秒>s
の形式を使用して指定し、各単位はオプションです。たとえば、1 時間半は1h30m
または90m
として指定できます。15 分 (15m) から 12 時間 (12h) の間である必要があります。policy
- (オプション) 引き受ける IAM ロールの権限をさらに制限する IAM ポリシーの JSON。policy_arns
- (オプション) 引き受ける IAM ロールの権限をさらに制限する IAM ポリシーの Amazon リソースネーム (ARN) のセット。session_name
- (オプション) ロールを引き受けるときに使用するセッション名。AWS_ROLE_SESSION_NAME
環境変数でも設定できます。web_identity_token
- (オプション) OpenID Connect (OIDC) または OAuth プロバイダーからのウェブ ID トークンの値。web_identity_token
またはweb_identity_token_file
のいずれかが必要です。web_identity_token_file
- (オプション) OpenID Connect (OIDC) または OAuth プロバイダーからのウェブ ID トークンを含むファイル。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
- (オプション) 非推奨 AWS S3 API のカスタムエンドポイント。これはAWS_S3_ENDPOINT
環境変数からも取得できます。force_path_style
- (オプション) 非推奨 パススタイルの S3 URL (https://<HOST>/<BUCKET>
の代わりにhttps://<BUCKET>.<HOST>
) を有効にします。代わりにuse_path_style
を使用してください。use_path_style
- (オプション) パススタイルの S3 URL (https://<HOST>/<BUCKET>
の代わりにhttps://<BUCKET>.<HOST>
) を有効にします。kms_key_id
- (オプション) ステートの暗号化に使用するキー管理サービス (KMS) キーの Amazon リソースネーム (ARN)。この値を指定した場合、OpenTofu はこの KMS キーに対するkms:Encrypt
、kms:Decrypt
およびkms:GenerateDataKey
権限が必要になることに注意してください。sse_customer_key
- (オプション) サーバー側のカスタマー提供キーによる暗号化 (SSE-C)でステートを暗号化するために使用するキー。これは、256ビットにデコードする必要があるキーのbase64エンコードされた値です。この値は、AWS_SSE_CUSTOMER_KEY
環境変数から取得することもできます。この値は機密性が高いため、環境変数からの取得が推奨されます。OpenTofuファイル内で設定すると、terraform.tfstate
にディスクに保存されます。workspace_key_prefix
- (オプション) バケット内のステートパスに適用されるプレフィックス。これは、デフォルト以外のワークスペースを使用する場合にのみ関連します。デフォルトはenv:
です。
DynamoDBステートロック
次の設定はオプションです。
dynamodb_endpoint
- (オプション) 非推奨 AWS DynamoDB APIのカスタムエンドポイント。これは、AWS_DYNAMODB_ENDPOINT
環境変数から取得することもできます。dynamodb_table
- (オプション) ステートロックと整合性に使用するDynamoDBテーブルの名前。テーブルには、LockID
という名前でタイプがString
のパーティションキーが必要です。設定されていない場合、ステートロックは無効になります。
マルチアカウントAWSアーキテクチャ
一般的なアーキテクチャパターンとして、組織が複数の独立したAWSアカウントを使用して、異なるチームや環境を分離することがあります。たとえば、ステージングシステムは、ステージング環境が本番インフラストラクチャに影響を与えるリスク(レート制限、誤って設定されたアクセス制御、その他の意図しない相互作用など)を最小限に抑えるために、対応する本番システムとは異なるAWSアカウントにデプロイされることがよくあります。
S3バックエンドは、このような組織において、利便性、セキュリティ、分離の間で異なるトレードオフを行うさまざまな方法で使用できます。このセクションでは、これらのトレードオフの間で適切な妥協点を見つけ、OpenTofuのワークスペース機能を使用して、同じ構成の複数の分離されたデプロイメントを便利に切り替えられるようにすることを目指したアプローチについて説明します。
このセクションをあなたのアプローチの出発点として使用してください。ただし、あなたの組織に適用される固有の標準と規制に合わせて調整する必要があるでしょう。また、たとえば他のツールが以前にインフラストラクチャの管理に使用されていた場合、組織内の既存のプラクティスを考慮して、このアプローチに調整を加える必要もあります。
OpenTofuは、インフラストラクチャを管理する管理ツールであるため、理想的には、OpenTofuが使用するインフラストラクチャは、OpenTofuが管理するインフラストラクチャの外に存在する必要があります。これは、人間のオペレーターが使用するユーザーアカウントと、他のアカウントの管理に使用するインフラストラクチャおよびツールを含む、別の管理AWSアカウントを作成することで実現できます。共有管理ツールをメイン環境から分離することには、いくつかの利点があります。たとえば、ターゲットインフラストラクチャを変更中に誤って管理インフラストラクチャを損傷することを回避したり、攻撃者が本番インフラストラクチャを悪用して、(通常はより特権的な)管理インフラストラクチャへのアクセスを得るリスクを減らすことができます。
管理アカウントのセットアップ
管理AWSアカウントには、少なくとも次の項目が含まれます
- 他のアカウントのインフラストラクチャを保守するためにログインするシステム管理者用の1つ以上のIAMユーザー。
- オプションで、他のAWSアカウントへのアクセスレベルが異なるユーザーのグループを区別するための1つ以上のIAMグループ。
- 各ワークスペースのOpenTofuステートファイルを含むS3バケット。
- 単一のワークスペースでの同時操作を防ぐためのロックに使用されるDynamoDBテーブル。
bucket
およびdynamodb_table
引数を使用してS3バックエンド構成内でS3バケット名とDynamoDBテーブル名をOpenTofuに提供し、この構成のために後で作成されるさまざまなワークスペースのステートを保持するための適切なworkspace_key_prefix
を構成します。
環境アカウントのセットアップ
このセクションでは、「環境アカウント」という用語は、上記で説明した管理アカウントとは別に、OpenTofuによって内容が管理されるアカウントの1つを指します。
環境アカウントには、最終的に製品固有のインフラストラクチャが含まれます。これとともに、OpenTofuが目的の管理タスクを実行するのに十分なアクセス権を付与する1つ以上のIAMロールが含まれている必要があります。
アクセス権の委任
各管理者は、管理アカウント内のIAMユーザーの認証情報を使用してOpenTofuを実行します。IAMロール委任は、これらのユーザーに各環境アカウントで作成されたロールへのアクセス権を付与するために使用されます。
ロール委任の詳細については、上記のAWSドキュメントに記載されています。最も重要な詳細は次のとおりです。
- 各ロールのロールの引き受けポリシーは、管理AWSアカウントにアクセス権を付与する必要があります。これにより、管理AWSアカウントとの信頼関係が構築され、そのユーザーがロールを引き受けることができます。
- 管理アカウント内のユーザーまたはグループは、このユーザーまたはグループがロールを引き受けることができるように、逆の関係を作成するポリシーを持っている必要もあります。
管理アカウントの目的は、他のアカウントを管理するためのツールをホストすることだけであるため、管理アカウントには、環境アカウントロールを引き受け、OpenTofuステートにアクセスするために必要な特定の操作のみに制限されたアクセス権を付与すると便利です。他のすべてのアクセスをブロックすることにより、ユーザーエラーによって、ステージングまたは本番リソースが誤って管理アカウントに作成されるリスクを排除します。
OpenTofuを構成するときは、環境変数または標準の認証情報ファイル~/.aws/credentials
のいずれかを使用して、S3バックエンドと OpenTofuのAWSプロバイダーの両方に、管理アカウント内の管理者ユーザーのIAM認証情報を提供します。
選択したワークスペースに応じて、別のassume_role
値をAWSプロバイダーに渡すには、条件付き構成を使用します。例:
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構成間で共有されている場合、これらの値を繰り返すことを避けるために、terraform_remote_state
などのデータソースを介してロールARNを取得することもできます。
ワークスペースの作成と選択
必要なオブジェクトが作成され、バックエンドが構成されたら、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"!
...
AWSプロバイダー構成のassume_role
設定により、AWSリソースの管理操作は、適切な環境AWSアカウントで構成されたロールを介して実行されます。S3からのステートの読み取りと書き込みなどのバックエンド操作は、管理アカウント内の管理者自身のユーザーとして直接実行されます。
$ tofu workspace select staging
$ tofu apply
...
Amazon EC2でのOpenTofuの実行
インフラストラクチャ管理にOpenTofuを広範に使用するチームは、一貫した運用環境を確保し、OpenTofu構成が必要とするさまざまなシークレットやその他の機密情報へのアクセスを制限するために、OpenTofuを自動化で実行することがよくあります。
Amazon EC2インスタンスで実行されている自動化ツールでOpenTofuを実行する場合は、このインスタンスを管理アカウントで実行し、上記のさまざまな管理者IAMユーザーの代わりにインスタンスプロファイルを使用することを検討してください。IAMインスタンスプロファイルには、IAMポリシーを介してクロスアカウント委任アクセス権を付与することもでき、このインスタンスにOpenTofuを実行するために必要なアクセス権を付与できます。
さまざまな環境アカウントへのアクセスを分離するには、各ターゲットアカウントに対して個別のEC2インスタンスを使用し、そのアクセスを単一のアカウントのみに制限できるようにします。
ECSなど、他のAWSコンピュートサービスで同等の機能を使用しても同様のアプローチを取ることができます。
ワークスペースステートへのアクセスの保護
前のセクションで説明したパターンの単純な実装では、すべてのユーザーがすべてのワークスペースのステートを読み書きするアクセス権を持っています。多くの場合、S3のOpenTofuステートオブジェクトにより正確なアクセス制約を適用することが望ましい場合があります。たとえば、信頼できる管理者のみが本番ステートを変更したり、機密情報を含むステートの読み取りを制御したりできるようにします。
Amazon S3は、IAMポリシーを使用して、オブジェクトパスごとに細かくアクセスを制御できます。S3のアクセス制御メカニズムの詳細な説明はこのガイドの範囲外ですが、S3バケット内の単一のステートオブジェクトのみにアクセスを許可するIAMポリシーの例を以下に示します。
{
"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
]
}
}
}
]
}
詳細については、DynamoDBのきめ細かいロックに関するAWSドキュメントを参照してください。
カスタムUser-Agent情報の構成
この機能はオプションであることに注意してください。
デフォルトでは、OpenTofu AWSプロバイダーで使用される基盤となるAWSクライアントは、OpenTofuおよびAWS Go SDKのバージョンに関する情報を含むUser-Agentヘッダーを使用してリクエストを作成します。User-Agentヘッダーに追加情報を提供するために、TF_APPEND_USER_AGENT
環境変数を設定できます。その値は、HTTPリクエストに直接追加されます。例:
$ export TF_APPEND_USER_AGENT="JenkinsAgent/i-12345678 BuildID/1234 (Optional Extra Information)"