Terraform

Terraform Remote Stateの共同作業と安全な運用(Associate対策と実務)

2026-04-19
NicheeLab編集部

Terraformの状態管理は、チーム運用では必ずRemote State前提になります。ローカル状態は衝突と秘匿性の両面で限界があり、バックエンド選定と運用設計が品質と速度を左右します。

本稿では公式ドキュメントの安定仕様に沿って、S3+DynamoDB、AzureRM、Terraform Cloudなどの代表バックエンドを比較し、確実なロックと暗号化、最小権限のアクセス制御、Workspaceの切り方、remote_state参照の注意点をまとめます。

Remote Stateの基本と、なぜ必要か

Terraformは計画・適用の判断材料として状態ファイル(state)を使います。stateにはリソースIDや属性、依存関係、しばしば機密性の高い値も含まれます。ローカル保存では編集競合や漏えいリスクが高いため、チームでは信頼できるリモートストレージに集約し、ロックと監査可能性を確保します。

ポイントは3つです。1) 競合防止: 同時実行をロックで制御 2) セキュリティ: 保管時暗号化と最小権限IAM/RBAC 3) 可観測性: 監査ログ、バージョニング、復旧手段。Terraform自体はstateを平文で保持する前提で動作するため、暗号化やアクセス制御はバックエンドの責務です。

  • TerraformはstateにSensitiveな値も保持する。CLI出力では秘匿できてもstate内は保護されないため、保管先の暗号化が必須
  • チームでの同時実行は競合を招く。確実なロック機構を持つバックエンドを使う
  • 状態のバックアップ・バージョニング・復旧計画を用意する

共同作業時のRemote Stateとロックの流れ(例:S3 + DynamoDB)

Dev Aterraform plan/applyDev Bterraform plan/applyRemote BackendS3 bucket, SSE-KMS, VersioningState Fileenv/prod/terraform.tfstateLock Table (DynamoDB)Acquire / Release LockIAM (Least Privilege)CloudTrail / LogsDev A/B が同一バックエンドを共有し、State 取得と Lock 取得/解放を経て安全に plan/apply を実行

最小構成のS3バックエンド例(ロックはDynamoDBで実現)

terraform {
  backend "s3" {
    bucket         = "my-tfstate-bucket"
    key            = "env/prod/app/terraform.tfstate"
    region         = "ap-northeast-1"
    dynamodb_table = "tf-state-lock"
    encrypt        = true
  }
}

# 実運用ではSSE-KMS、バージョニング、バケットポリシーでの制限を合わせて設定する

バックエンド比較と選定指針

選定基準は、ロックの確実性、暗号化とアクセス制御の容易さ、監査・バージョニング、運用コストです。クラウドネイティブなS3/AzureRMは導入が容易で、Terraform CloudのremoteはRBACやUI、チーム機能がまとまっています。

GCSは標準機能でのロックに制約があり(この前提は公式のサポート状況に依存)、強い整合・ロックが必須の大規模チームではS3+DynamoDBやAzureRM、Terraform Cloudを優先します。

  • ロック優先なら S3+DynamoDB / AzureRM / Terraform Cloud
  • コンプライアンスや運用ガバナンスが強い場合は Terraform Cloud/Enterprise でRBAC・ポリシーを集中管理
  • クラウド分断やクロスアカウント要件がある場合は、IAMロール委任やVPCエンドポイントで到達性・最小権限を詰める
バックエンドロック暗号化/保護アクセス制御/監査
S3 + DynamoDBあり(DynamoDBロック)SSE-S3/SSE-KMS、バージョニング可IAM + CloudTrail、Bucket Policy
AzureRM (Blob)あり(Blobリース)SSE/CMK、Soft Delete/VersioningAAD RBAC + 診断ログ
Terraform Cloud (remote)あり(サーバー側ロック)サーバー側暗号化、VCS連携組織RBAC、監査、ポリシー
GCS (Bucket)制約ありサーバー側暗号化/CMEKIAM + Cloud Audit Logs

部分的バックエンド設定とinit時の注入(-backend-config)

terraform {
  backend "s3" {}
}

# repoには値を固定せず、init時に注入して誤適用を防ぐ
# 例)環境ごとのCI/CDジョブで
# terraform init \
#   -backend-config=bucket=my-tfstate-bucket \
#   -backend-config=key=env/${ENV}/app/terraform.tfstate \
#   -backend-config=region=ap-northeast-1 \
#   -backend-config=dynamodb_table=tf-state-lock \
#   -reconfigure

セキュアな設計パターン(S3例)

Remote Stateは保管先のセキュリティに依存します。S3を例に、暗号化・最小権限・監査・復旧の4点を押さえます。Terraform自体はstateを暗号化しません。バックエンドの暗号化とアクセス制御が要です。

また、state肥大化を避けるため、不要なデータソースの格納や巨大なリソース属性の保持を抑え、出力(outputs)に機密を残さない方針を徹底します。

  • 暗号化: S3バケットはSSE-KMSを必須化し、KMSキーはローテーションと厳格なKey Policy
  • アクセス制御: バケットポリシーでPrincipalを限定。IAMロールにGetObject/PutObject/ListBucketのみ付与
  • ネットワーク: VPCエンドポイント経由のアクセス、Public Access Block有効化
  • 監査: バケットアクセスログ/CloudTrail有効化、バージョニングとMFA Delete(要件に応じて)
  • 整合性: DynamoDBロックテーブルはオンデマンド/適正なRCU/WCUとTTLで管理
  • 機密最小化: outputsにシークレットを出さない(どうしても必要なら短寿命トークン化)

S3バケット側の代表設定(参考・一部)

# バケットは事前に作成しておき、ポリシーでTerraformのロールのみ許可
# 例のポリシーフラグメント(概念例)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "s3:*",
      "Resource": [
        "arn:aws:s3:::my-tfstate-bucket",
        "arn:aws:s3:::my-tfstate-bucket/*"
      ],
      "Condition": {"Bool": {"aws:SecureTransport": "false"}}
    }
  ]
}

# KMSキーはTerraformロールにEncrypt/Decryptを付与し、外部主体を禁止
# バージョニングは有効化、パブリックアクセスは全面ブロック

共同作業フローとWorkspace戦略

環境分離は「ディレクトリ分割」か「Workspace活用」で行えます。Associateの観点では、stateの衝突回避と権限分離を優先し、明確な命名とアクセス境界を揃えることが重要です。Workspaceは同一設定で環境だけ切り替える用途に適します。

バックエンドのkeyはWorkspace名を埋め込むと安全です。Terraform Cloudのremoteを使う場合は、組織/ワークスペース単位でRBACと実行キュー、ロックが管理されます。

  • ディレクトリ分離: env/prod, env/stage などでstateを物理分離しやすい
  • Workspace: 同一コードで var や workspace名によりkeyを切替。過剰多用はドリフト把握を難しくする
  • 人の手での同時applyを避け、PR駆動+CI/CDで計画・承認・適用を一元化する

Workspace名でstate keyを切替(S3)

terraform {
  backend "s3" {
    bucket         = "my-tfstate-bucket"
    key            = "env/${terraform.workspace}/app/terraform.tfstate"
    region         = "ap-northeast-1"
    dynamodb_table = "tf-state-lock"
    encrypt        = true
  }
}

# 例
# terraform workspace new stage
# terraform workspace select stage
# terraform apply  # => env/stage/app/terraform.tfstate に書き込み

remote_stateデータ参照の安全設計

モジュール間で値を受け渡す場合、data "terraform_remote_state" を使うと、他スタックのoutputsを安全に参照できます。ただし、outputsに機密を出さないのが大原則です。state間の結合度が上がるため、キー命名や権限境界を明確にします。

バックエンドのcredは最小権限で、参照専用のロール(GetObjectのみ等)に分離します。Terraform Cloudのremote同士で参照する場合は、同組織内の適切なワークスペース参照機構とRBACを利用します。

  • 参照元からはoutputsしか見えない設計にし、内部属性に依存しない
  • outputsに長期秘密(パスワードや長寿命キー)を出さない
  • stateキーは変更に強い命名(env/system/component)にする

別スタックのVPC IDを参照(S3 backend例)

data "terraform_remote_state" "network" {
  backend = "s3"
  config = {
    bucket         = "my-tfstate-bucket"
    key            = "env/prod/network/terraform.tfstate"
    region         = "ap-northeast-1"
    dynamodb_table = "tf-state-lock"
    encrypt        = true
  }
}

output "subnet_ids" {
  value = data.terraform_remote_state.network.outputs.subnet_ids
}

# 注意: network側のoutputsに機密を置かない。参照用IAMはGetObject等の読み取り最小権限のみ

運用とトラブルシュート(ロック・移行・復旧)

ロックが残留する、バックエンドを変更したい、stateを復旧したい等の運用課題は必ず発生します。手順を定め、強制解除は最終手段に留めます。移行は計画停止時間内での検証とロールバック手段(バックアップ)の確保が重要です。

ドリフト検出はplan差分と監査ログを併用します。stateのサイズ肥大化やキー構成の複雑化は運用コスト増に直結するため、定期的なヘルスチェックをおすすめします。

  • ロック解放: terraform force-unlock は最終手段。実行中のapplyが無いことを必ず確認
  • バックエンド切替: terraform init -migrate-state -reconfigure で安全に移行。事前に state pull でバックアップ
  • 復旧: バックエンドのバージョニングからリストアし、terraform refresh/planで整合を確認
  • state操作: terraform state mv / rm は最少回数に留め、PRレビュー対象にする

代表的な運用コマンド

# ロックの強制解除(適用中断が無いことを確認した上で)
terraform force-unlock <LOCK_ID>

# stateのバックアップ
terraform state pull > backup-$(date +%F).tfstate

# バックエンド移行(例:S3 -> Terraform Cloud remote)
terraform init -migrate-state -reconfigure

# state内リソースのパス修正
terraform state mv aws_s3_bucket.old aws_s3_bucket.new

問題で確認

Associate

問題 1

チームでAWS上のインフラを管理しています。共同作業時の競合防止とセキュアな保管を最もシンプルに満たすRemote State構成はどれですか?

  1. S3バケットにstateを保存し、DynamoDBテーブルでロック、SSE-KMSとバージョニングを有効化する
  2. ローカルstateを各自のPCに保存し、Gitでtfstateを共有する
  3. GCSバケットにstateを保存し、ロックは特に設定しない
  4. S3バケットにstateを保存し、暗号化やロックは不要とする

正解: A

チームの同時実行を防ぐ確実なロック(DynamoDB)と、保管時暗号化(SSE-KMS)、復旧容易性(バージョニング)を満たすのがA。Bは競合と秘匿性の両面で不適切。CやDはロック/暗号化が不足する。

よくある質問

Terraformはstateを自動で暗号化しますか?

いいえ。Terraform自体はstateを暗号化しません。暗号化はバックエンド(S3のSSE-KMS、AzureのCMK、Terraform Cloudのサーバー側暗号化など)で実現します。

Workspaceとディレクトリ分割、どちらを使うべきですか?

同一構成を環境だけ切り替えるならWorkspaceが有効です。権限やライフサイクルを強く分離したい場合はディレクトリ(またはリポジトリ)分割でstateを物理分離する方が運用しやすいです。

ロックが残ってapplyできません。どうすれば良いですか?

実行中のTerraformがないことを確認した上で、まずバックエンド側(DynamoDBのロックレコード等)を確認します。問題なければ terraform force-unlock を最後の手段として使います。強制解除は競合リスクがあるため、チームで合意の上で実施してください。

この記事で学んだ内容を問題で確認しましょう

16,000問以上の問題で実力チェック

無料で問題を解いてみる
この記事の著者

NicheeLab編集部

データエンジニアリング・クラウド資格の専門家。Databricks・Snowflake等の認定資格を保有し、実務経験に基づいた問題作成・解説を行っています。NicheeLab運営。


関連記事
Terraform

Terraform HCL 構文の基礎:Block / Attribute / Expression を正しく使い分ける

Terraform Associate で頻出の HCL 構文を、ブロック・属性・式の3視点で整理。実務で迷いがちな書き...

Terraform

Terraform Authoring & Ops Pro: 上位資格の範囲と対策

上位レベルを想定したTerraformの設計・運用ドメインを整理し、実務で通用する対策を提示。モジュール設計、ステート運...

Terraform

Terraform Providers の基本: プラグイン型アーキテクチャを正しく使いこなす

Associate レベルで押さえるべき Provider の基礎、インストール、バージョニング、認証、エイリアス運用を...

Terraform

Terraform Resourceブロック徹底ガイド: 最小単位のリソース定義

Associateレベルで押さえるべきResourceブロックの構造、依存関係、メタ引数、ライフサイクル制御を実務目線で...

Terraform

Terraform Data Source徹底理解:既存リソースの参照で壊さず足す

Terraform Associate向けに、Data Sourceを用いた既存リソース参照の基本、選択基準、評価順序、...

Terraformの記事一覧 (102件)
© 2026 NicheeLab All rights reserved.